Browse Source

Added DynamicResourceExtension.

pull/1136/head
Steven Kirk 9 years ago
parent
commit
38dce7b7cd
  1. 1
      src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
  2. 41
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs
  3. 285
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceTests.cs
  4. 2
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceTests.cs

1
src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj

@ -34,6 +34,7 @@
<Compile Include="Converters\MatrixTypeConverter.cs" />
<Compile Include="Converters\RectTypeConverter.cs" />
<Compile Include="Converters\SetterValueTypeConverter.cs" />
<Compile Include="MarkupExtensions\DynamicResourceExtension.cs" />
<Compile Include="MarkupExtensions\StaticResourceExtension.cs" />
<Compile Include="MarkupExtensions\StyleIncludeExtension.cs" />
<Compile Include="PortableXaml\AvaloniaXamlContext.cs" />

41
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;
}
}
}

285
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 = @"
<UserControl xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<UserControl.Resources>
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
</UserControl.Resources>
<Border Name='border' Background='{DynamicResource brush}'/>
</UserControl>";
var loader = new AvaloniaXamlLoader();
var userControl = (UserControl)loader.Load(xaml);
var border = userControl.FindControl<Border>("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 = @"
<UserControl xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<UserControl.Styles>
<Style>
<Style.Resources>
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
</Style.Resources>
</Style>
</UserControl.Styles>
<Border Name='border' Background='{DynamicResource brush}'/>
</UserControl>";
var loader = new AvaloniaXamlLoader();
var userControl = (UserControl)loader.Load(xaml);
var border = userControl.FindControl<Border>("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 = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Border Name='border' Background='{DynamicResource brush}'/>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var border = window.FindControl<Border>("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 = @"
<UserControl xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Border Name='border' Background='{DynamicResource brush}'/>
</UserControl>";
var loader = new AvaloniaXamlLoader();
var userControl = (UserControl)loader.Load(xaml);
var border = userControl.FindControl<Border>("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 = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.Resources>
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
</Window.Resources>
<Window.Styles>
<Style Selector='Button'>
<Setter Property='Background' Value='{DynamicResource brush}'/>
</Style>
</Window.Styles>
<Button Name='button'/>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var button = window.FindControl<Button>("button");
var brush = (SolidColorBrush)button.Background;
Assert.Equal(0xff506070, brush.Color.ToUint32());
}
}
[Fact]
public void DynamicResource_From_Style_Can_Be_Assigned_To_Setter()
{
using (StyledWindow())
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.Styles>
<Style>
<Style.Resources>
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
</Style.Resources>
</Style>
<Style Selector='Button'>
<Setter Property='Background' Value='{DynamicResource brush}'/>
</Style>
</Window.Styles>
<Button Name='button'/>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var button = window.FindControl<Button>("button");
var brush = (SolidColorBrush)button.Background;
Assert.Equal(0xff506070, brush.Color.ToUint32());
}
}
[Fact]
public void DynamicResource_Can_Be_Assigned_To_Setter_In_Styles_File()
{
var styleXaml = @"
<Styles xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Styles.Resources>
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
</Styles.Resources>
<Style Selector='Border'>
<Setter Property='Background' Value='{DynamicResource brush}'/>
</Style>
</Styles>";
using (StyledWindow(assets: ("test:style.xaml", styleXaml)))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.Styles>
<StyleInclude Source='test:style.xaml'/>
</Window.Styles>
<Border Name='border'/>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var border = window.FindControl<Border>("border");
var brush = (SolidColorBrush)border.Background;
Assert.Equal(0xff506070, brush.Color.ToUint32());
}
}
[Fact]
public void DynamicResource_Can_Be_Assigned_To_Property_In_ControlTemplate_In_Styles_File()
{
var styleXaml = @"
<Styles xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Styles.Resources>
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
</Styles.Resources>
<Style Selector='Button'>
<Setter Property='Template'>
<ControlTemplate>
<Border Name='border' Background='{DynamicResource brush}'/>
</ControlTemplate>
</Setter>
</Style>
</Styles>";
using (StyledWindow(assets: ("test:style.xaml", styleXaml)))
{
var xaml = @"
<Window xmlns='https://github.com/avaloniaui'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<Window.Styles>
<StyleInclude Source='test:style.xaml'/>
</Window.Styles>
<Button Name='button'/>
</Window>";
var loader = new AvaloniaXamlLoader();
var window = (Window)loader.Load(xaml);
var button = window.FindControl<Button>("button");
window.Show();
var border = (Border)button.GetVisualChildren().Single();
var brush = (SolidColorBrush)border.Background;
Assert.Equal(0xff506070, brush.Color.ToUint32());
}
}
private IDisposable StyledWindow(params (string, string)[] assets)
{
var services = TestServices.StyledWindow.With(
assetLoader: new MockAssetLoader(assets),
theme: () => new Styles
{
WindowStyle(),
});
return UnitTestApplication.Start(services);
}
private Style WindowStyle()
{
return new Style(x => x.OfType<Window>())
{
Setters =
{
new Setter(
Window.TemplateProperty,
new FuncControlTemplate<Window>(x =>
new ContentPresenter
{
Name = "PART_ContentPresenter",
[!ContentPresenter.ContentProperty] = x[!Window.ContentProperty],
}))
}
};
}
}
}

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

@ -17,7 +17,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
public class StaticResourceTests
{
[Fact]
public void StaticResource_Style_Can_Be_Assigned_To_Property()
public void StaticResource_Can_Be_Assigned_To_Property()
{
var xaml = @"
<UserControl xmlns='https://github.com/avaloniaui'

Loading…
Cancel
Save