diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs index 45fece49e5..4bb0913a2e 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs @@ -2,14 +2,19 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; +using System.ComponentModel; using Avalonia.Controls; using Avalonia.Data; +using Portable.Xaml; +using Portable.Xaml.ComponentModel; using Portable.Xaml.Markup; namespace Avalonia.Markup.Xaml.MarkupExtensions { public class DynamicResourceExtension : MarkupExtension, IBinding { + private IControl _anchor; + public DynamicResourceExtension() { } @@ -21,7 +26,18 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions public string ResourceKey { get; set; } - public override object ProvideValue(IServiceProvider serviceProvider) => this; + public override object ProvideValue(IServiceProvider serviceProvider) + { + var context = (ITypeDescriptorContext)serviceProvider; + var provideTarget = context.GetService(); + + if (!(provideTarget.TargetObject is IControl)) + { + _anchor = GetAnchor(context); + } + + return this; + } InstancedBinding IBinding.Initiate( IAvaloniaObject target, @@ -29,7 +45,9 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions object anchor, bool enableDataValidation) { - if (target is IControl control) + var control = target as IControl ?? _anchor as IControl; + + if (control != null) { var resource = control.FindResource(ResourceKey); return new InstancedBinding(resource); @@ -37,5 +55,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions return null; } + + private T GetAnchor(ITypeDescriptorContext context) where T : class + { + var schemaContext = context.GetService()?.SchemaContext; + var ambientProvider = context.GetService(); + var xamlType = schemaContext.GetXamlType(typeof(T)); + return ambientProvider.GetFirstAmbientValue(xamlType) as T; + } } } diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs index d071f78076..e6d5dd99a3 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs @@ -277,7 +277,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } [Fact] - public void DynamicResource_Can_Be_Found_Across_Xaml_Files() + public void DynamicResource_Can_Be_Found_Across_Xaml_Style_Files() { var style1Xaml = @"