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 +}