From 3f87b9d02d1171a0078bd9c9a17db9cee1a58302 Mon Sep 17 00:00:00 2001 From: Amadeusz Sadowski Date: Fri, 20 Apr 2018 15:24:09 +0200 Subject: [PATCH] Support StaticResource in Bindings inside DataTemplate --- .../AvaloniaXamlLoaderPortableXaml.cs | 5 +-- .../PortableXaml/AvaloniaXamlObjectWriter.cs | 26 ++++++++++++-- .../PortableXaml/portable.xaml.github | 2 +- .../Templates/TemplateContent.cs | 8 +++-- .../Templates/TemplateLoader.cs | 3 +- .../StaticResourceExtensionTests.cs | 36 ++++++++++++++++++- 6 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs index de2a79c54e..539fbeb680 100644 --- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs +++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoaderPortableXaml.cs @@ -194,11 +194,12 @@ namespace Avalonia.Markup.Xaml return result; } - internal static object LoadFromReader(XamlReader reader, AvaloniaXamlContext context = null) + internal static object LoadFromReader(XamlReader reader, AvaloniaXamlContext context = null, IAmbientProvider parentAmbientProvider = null) { var writer = AvaloniaXamlObjectWriter.Create( reader.SchemaContext, - context); + context, + parentAmbientProvider); XamlServices.Transform(reader, writer); writer.ApplyAllDelayedProperties(); diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs index e0e2553f46..509c52503b 100644 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs @@ -27,6 +27,26 @@ namespace Avalonia.Markup.Xaml.PortableXaml nameScope); } + public static AvaloniaXamlObjectWriter Create( + XamlSchemaContext schemaContext, + AvaloniaXamlContext context, + IAmbientProvider parentAmbientProvider) + { + var nameScope = new AvaloniaNameScope { Instance = context?.RootInstance }; + + var writerSettings = new XamlObjectWriterSettings() + { + ExternalNameScope = nameScope, + RegisterNamesOnExternalNamescope = true, + RootObjectInstance = context?.RootInstance + }; + + return new AvaloniaXamlObjectWriter(schemaContext, + writerSettings.WithContext(context), + nameScope, + parentAmbientProvider); + } + private readonly DelayedValuesHelper _delayedValuesHelper = new DelayedValuesHelper(); private AvaloniaNameScope _nameScope; @@ -34,9 +54,9 @@ namespace Avalonia.Markup.Xaml.PortableXaml private AvaloniaXamlObjectWriter( XamlSchemaContext schemaContext, XamlObjectWriterSettings settings, - AvaloniaNameScope nameScope - ) - : base(schemaContext, settings) + AvaloniaNameScope nameScope, + IAmbientProvider parentAmbientProvider = null) + : base(schemaContext, settings, parentAmbientProvider) { _nameScope = nameScope; } diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github index c066401445..e7077fa7df 160000 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github @@ -1 +1 @@ -Subproject commit c0664014455392ac221a765e66f9837704339b6f +Subproject commit e7077fa7df836af53f220f845f59971208c3e408 diff --git a/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cs b/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cs index 1d4dafc413..63fb9f193c 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateContent.cs @@ -10,8 +10,10 @@ namespace Avalonia.Markup.Xaml.Templates public class TemplateContent { - public TemplateContent(IEnumerable namespaces, XamlReader reader) + public TemplateContent(IEnumerable namespaces, XamlReader reader, + IAmbientProvider ambientProvider) { + ParentAmbientProvider = ambientProvider; List = new XamlNodeList(reader.SchemaContext); //we need to rpeserve all namespace and prefixes to writer @@ -26,9 +28,11 @@ namespace Avalonia.Markup.Xaml.Templates public XamlNodeList List { get; } + private IAmbientProvider ParentAmbientProvider { get; } + public IControl Load() { - return (IControl)AvaloniaXamlLoader.LoadFromReader(List.GetReader()); + return (IControl)AvaloniaXamlLoader.LoadFromReader(List.GetReader(), parentAmbientProvider: ParentAmbientProvider); } public static IControl Load(object templateContent) diff --git a/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateLoader.cs b/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateLoader.cs index 1085131230..e29485ddb0 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateLoader.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Templates/TemplateLoader.cs @@ -14,7 +14,8 @@ namespace Avalonia.Markup.Xaml.Templates { var tdc = (ITypeDescriptorContext)serviceProvider; var ns = tdc.GetService(); - return new TemplateContent(ns.GetNamespacePrefixes(), xamlReader); + var ambientProvider = tdc.GetService(); + return new TemplateContent(ns.GetNamespacePrefixes(), xamlReader, ambientProvider); } public override XamlReader Save(object value, IServiceProvider serviceProvider) diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs index 862ce2b3c0..57293d5d16 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs @@ -323,7 +323,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions Assert.Equal(0xff506070, brush.Color.ToUint32()); } - [Fact(Skip = "Not yet supported by Portable.Xaml")] + [Fact(/*Skip = "Not yet supported by Portable.Xaml"*/)] public void StaticResource_Can_Be_Assigned_To_Property_In_ControlTemplate_In_Styles_File() { var styleXaml = @" @@ -417,6 +417,40 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions } } + [Fact] + public void StaticResource_Can_Be_Assigned_To_Converter_In_DataTemplate() + { + using (StyledWindow()) + { + var xaml = @" + + + + + + + + + +"; + + var loader = new AvaloniaXamlLoader(); + var window = (Window)loader.Load(xaml); + + window.DataContext = "foo"; + var presenter = window.FindControl("presenter"); + + window.Show(); + + var textBlock = (TextBlock)presenter.GetVisualChildren().Single(); + + Assert.NotNull(textBlock); + Assert.Equal("foobar", textBlock.Text); + } + } + [Fact] public void Control_Property_Is_Not_Updated_When_Parent_Is_Changed() {