Browse Source

Use an anchor for dynamic resources.

pull/1136/head
Steven Kirk 9 years ago
parent
commit
b459445290
  1. 30
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs
  2. 2
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs

30
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. // Licensed under the MIT license. See licence.md file in the project root for full license information.
using System; using System;
using System.ComponentModel;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Data; using Avalonia.Data;
using Portable.Xaml;
using Portable.Xaml.ComponentModel;
using Portable.Xaml.Markup; using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.MarkupExtensions namespace Avalonia.Markup.Xaml.MarkupExtensions
{ {
public class DynamicResourceExtension : MarkupExtension, IBinding public class DynamicResourceExtension : MarkupExtension, IBinding
{ {
private IControl _anchor;
public DynamicResourceExtension() public DynamicResourceExtension()
{ {
} }
@ -21,7 +26,18 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public string ResourceKey { get; set; } 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<IProvideValueTarget>();
if (!(provideTarget.TargetObject is IControl))
{
_anchor = GetAnchor<IControl>(context);
}
return this;
}
InstancedBinding IBinding.Initiate( InstancedBinding IBinding.Initiate(
IAvaloniaObject target, IAvaloniaObject target,
@ -29,7 +45,9 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
object anchor, object anchor,
bool enableDataValidation) bool enableDataValidation)
{ {
if (target is IControl control) var control = target as IControl ?? _anchor as IControl;
if (control != null)
{ {
var resource = control.FindResource(ResourceKey); var resource = control.FindResource(ResourceKey);
return new InstancedBinding(resource); return new InstancedBinding(resource);
@ -37,5 +55,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
return null; return null;
} }
private T GetAnchor<T>(ITypeDescriptorContext context) where T : class
{
var schemaContext = context.GetService<IXamlSchemaContextProvider>()?.SchemaContext;
var ambientProvider = context.GetService<IAmbientProvider>();
var xamlType = schemaContext.GetXamlType(typeof(T));
return ambientProvider.GetFirstAmbientValue(xamlType) as T;
}
} }
} }

2
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs

@ -277,7 +277,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
} }
[Fact] [Fact]
public void DynamicResource_Can_Be_Found_Across_Xaml_Files() public void DynamicResource_Can_Be_Found_Across_Xaml_Style_Files()
{ {
var style1Xaml = @" var style1Xaml = @"
<Style xmlns='https://github.com/avaloniaui' <Style xmlns='https://github.com/avaloniaui'

Loading…
Cancel
Save