From 38dce7b7cd50dd47939459edc59c165f55da89c5 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 23 Aug 2017 13:47:59 +0200 Subject: [PATCH] Added DynamicResourceExtension. --- .../Avalonia.Markup.Xaml.csproj | 1 + .../DynamicResourceExtension.cs | 41 +++ .../MarkupExtensions/DynamicResourceTests.cs | 285 ++++++++++++++++++ .../MarkupExtensions/StaticResourceTests.cs | 2 +- 4 files changed, 328 insertions(+), 1 deletion(-) create mode 100644 src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs create mode 100644 tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index efb8ea4cc5..5c2d228e62 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -34,6 +34,7 @@ + diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs new file mode 100644 index 0000000000..45fece49e5 --- /dev/null +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs @@ -0,0 +1,41 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using Avalonia.Controls; +using Avalonia.Data; +using Portable.Xaml.Markup; + +namespace Avalonia.Markup.Xaml.MarkupExtensions +{ + public class DynamicResourceExtension : MarkupExtension, IBinding + { + public DynamicResourceExtension() + { + } + + public DynamicResourceExtension(string resourceKey) + { + ResourceKey = resourceKey; + } + + public string ResourceKey { get; set; } + + public override object ProvideValue(IServiceProvider serviceProvider) => this; + + InstancedBinding IBinding.Initiate( + IAvaloniaObject target, + AvaloniaProperty targetProperty, + object anchor, + bool enableDataValidation) + { + if (target is IControl control) + { + var resource = control.FindResource(ResourceKey); + return new InstancedBinding(resource); + } + + return null; + } + } +} diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs new file mode 100644 index 0000000000..70c45c3e7f --- /dev/null +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs @@ -0,0 +1,285 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using System; +using System.Linq; +using Avalonia.Controls; +using Avalonia.Controls.Presenters; +using Avalonia.Controls.Templates; +using Avalonia.Markup.Xaml.Data; +using Avalonia.Media; +using Avalonia.Styling; +using Avalonia.UnitTests; +using Avalonia.VisualTree; +using Xunit; + +namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions +{ + public class DynamicResourceTests + { + [Fact] + public void DynamicResource_Can_Be_Assigned_To_Property() + { + var xaml = @" + + + #ff506070 + + + +"; + + var loader = new AvaloniaXamlLoader(); + var userControl = (UserControl)loader.Load(xaml); + var border = userControl.FindControl("border"); + + DelayedBinding.ApplyBindings(border); + + var brush = (SolidColorBrush)border.Background; + Assert.Equal(0xff506070, brush.Color.ToUint32()); + } + + [Fact] + public void DynamicResource_From_Style_Can_Be_Assigned_To_Property() + { + var xaml = @" + + + + + + +"; + + var loader = new AvaloniaXamlLoader(); + var userControl = (UserControl)loader.Load(xaml); + var border = userControl.FindControl("border"); + + DelayedBinding.ApplyBindings(border); + + var brush = (SolidColorBrush)border.Background; + Assert.Equal(0xff506070, brush.Color.ToUint32()); + } + + [Fact] + public void DynamicResource_From_Application_Can_Be_Assigned_To_Property_In_Window() + { + using (StyledWindow()) + { + Application.Current.Resources.Add("brush", new SolidColorBrush(0xff506070)); + + var xaml = @" + + +"; + + var loader = new AvaloniaXamlLoader(); + var window = (Window)loader.Load(xaml); + var border = window.FindControl("border"); + + var brush = (SolidColorBrush)border.Background; + Assert.Equal(0xff506070, brush.Color.ToUint32()); + } + } + + [Fact] + public void DynamicResource_From_Application_Can_Be_Assigned_To_Property_In_UserControl() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + Application.Current.Resources.Add("brush", new SolidColorBrush(0xff506070)); + + var xaml = @" + + +"; + + var loader = new AvaloniaXamlLoader(); + var userControl = (UserControl)loader.Load(xaml); + var border = userControl.FindControl("border"); + + // We don't actually know where the global styles are until we attach the control + // to a window, as Window has StylingParent set to Application. + var window = new Window { Content = userControl }; + window.Show(); + + var brush = (SolidColorBrush)border.Background; + Assert.Equal(0xff506070, brush.Color.ToUint32()); + } + } + + [Fact] + public void DynamicResource_Can_Be_Assigned_To_Setter() + { + using (StyledWindow()) + { + var xaml = @" + + + #ff506070 + + + + +