diff --git a/src/Avalonia.Base/AvaloniaPropertyRegistry.cs b/src/Avalonia.Base/AvaloniaPropertyRegistry.cs
index c0a4ace6ed..e29e7339ae 100644
--- a/src/Avalonia.Base/AvaloniaPropertyRegistry.cs
+++ b/src/Avalonia.Base/AvaloniaPropertyRegistry.cs
@@ -106,7 +106,7 @@ namespace Avalonia
}
///
- /// Finds a registered non-attached property on a type by name.
+ /// Finds a registered property on a type by name.
///
/// The type.
/// The property name.
@@ -130,7 +130,7 @@ namespace Avalonia
}
///
- /// Finds a registered non-attached property on a type by name.
+ /// Finds a registered property on an object by name.
///
/// The object.
/// The property name.
@@ -148,52 +148,6 @@ namespace Avalonia
return FindRegistered(o.GetType(), name);
}
- ///
- /// Finds a registered attached property on a type by name.
- ///
- /// The type.
- /// The owner type.
- /// The property name.
- ///
- /// The registered property or null if no matching property found.
- ///
- ///
- /// The property name contains a '.'.
- ///
- public AvaloniaProperty FindRegisteredAttached(Type type, Type ownerType, string name)
- {
- Contract.Requires(type != null);
- Contract.Requires(ownerType != null);
- Contract.Requires(name != null);
-
- if (name.Contains('.'))
- {
- throw new InvalidOperationException("Attached properties not supported.");
- }
-
- return GetRegisteredAttached(type).FirstOrDefault(x => x.Name == name);
- }
-
- ///
- /// Finds a registered non-attached property on a type by name.
- ///
- /// The object.
- /// The owner type.
- /// The property name.
- ///
- /// The registered property or null if no matching property found.
- ///
- ///
- /// The property name contains a '.'.
- ///
- public AvaloniaProperty FindRegisteredAttached(AvaloniaObject o, Type ownerType, string name)
- {
- Contract.Requires(o != null);
- Contract.Requires(name != null);
-
- return FindRegisteredAttached(o.GetType(), ownerType, name);
- }
-
///
/// Checks whether a is registered on a type.
///
@@ -287,4 +241,4 @@ namespace Avalonia
_attachedCache.Clear();
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Markup/Avalonia.Markup/Markup/Parsers/Reader.cs b/src/Avalonia.Base/Utilities/CharacterReader.cs
similarity index 89%
rename from src/Markup/Avalonia.Markup/Markup/Parsers/Reader.cs
rename to src/Avalonia.Base/Utilities/CharacterReader.cs
index 9355bc9aa3..0910d5b969 100644
--- a/src/Markup/Avalonia.Markup/Markup/Parsers/Reader.cs
+++ b/src/Avalonia.Base/Utilities/CharacterReader.cs
@@ -3,14 +3,14 @@
using System;
-namespace Avalonia.Markup.Parsers
+namespace Avalonia.Utilities
{
- internal class Reader
+ public class CharacterReader
{
private readonly string _s;
private int _i;
- public Reader(string s)
+ public CharacterReader(string s)
{
_s = s;
}
diff --git a/src/Markup/Avalonia.Markup/Markup/Parsers/IdentifierParser.cs b/src/Avalonia.Base/Utilities/IdentifierParser.cs
similarity index 91%
rename from src/Markup/Avalonia.Markup/Markup/Parsers/IdentifierParser.cs
rename to src/Avalonia.Base/Utilities/IdentifierParser.cs
index f86f2db321..14b8affbdd 100644
--- a/src/Markup/Avalonia.Markup/Markup/Parsers/IdentifierParser.cs
+++ b/src/Avalonia.Base/Utilities/IdentifierParser.cs
@@ -4,11 +4,11 @@
using System.Globalization;
using System.Text;
-namespace Avalonia.Markup.Parsers
+namespace Avalonia.Utilities
{
- internal static class IdentifierParser
+ public static class IdentifierParser
{
- public static string Parse(Reader r)
+ public static string Parse(CharacterReader r)
{
if (IsValidIdentifierStart(r.Peek))
{
diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
index cdc22f4102..8c843a4b49 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
+++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
@@ -33,6 +33,7 @@
+
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
index 63b7811dbc..627a646bcf 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
@@ -4,19 +4,19 @@
using System;
using System.ComponentModel;
using System.Globalization;
-using System.Text.RegularExpressions;
+using Avalonia.Controls;
+using Avalonia.Logging;
+using Avalonia.Markup.Parsers;
+using Avalonia.Markup.Xaml.Parsers;
using Avalonia.Markup.Xaml.Templates;
using Avalonia.Styling;
-using Portable.Xaml;
+using Avalonia.Utilities;
using Portable.Xaml.ComponentModel;
-using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.Converters
{
public class AvaloniaPropertyTypeConverter : TypeConverter
{
- private static readonly Regex regex = new Regex(@"^\(?(\w*)\.(\w*)\)?|(.*)$");
-
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string);
@@ -24,39 +24,48 @@ namespace Avalonia.Markup.Xaml.Converters
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
- var (owner, propertyName) = ParseProperty((string)value);
- var ownerType = TryResolveOwnerByName(context, owner) ??
- context.GetFirstAmbientValue()?.TargetType ??
- context.GetFirstAmbientValue
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = (TextBlock)window.Content;
+
+ window.DataContext = 5.6;
+ window.ApplyTemplate();
+
+ Assert.Equal(5.6, AttachedPropertyOwner.GetDouble(textBlock));
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
index 2c7e850fee..beaf7477d0 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
@@ -7,6 +7,7 @@ using Avalonia.Markup.Xaml.Styling;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.UnitTests;
+using Portable.Xaml;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
@@ -146,5 +147,56 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.NotNull(target.FocusAdorner);
}
}
+
+ [Fact]
+ public void Setter_Can_Set_Attached_Property()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var xaml = @"
+
+
+
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = (TextBlock)window.Content;
+
+ window.ApplyTemplate();
+
+ Assert.Equal(Dock.Right, DockPanel.GetDock(textBlock));
+ }
+ }
+
+ [Fact(Skip = "The animation system currently needs to be able to set any property on any object")]
+ public void Disallows_Setting_Non_Registered_Property()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+ var xaml = @"
+
+
+
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var ex = Assert.Throws(() => loader.Load(xaml));
+
+ Assert.Equal(
+ "Property 'Button.IsDefault' is not registered on 'Avalonia.Controls.TextBlock'.",
+ ex.InnerException.Message);
+ }
+ }
}
-}
\ No newline at end of file
+}