From 67ea597d82e14a6e9feeeb83d6d34fbda15b215a Mon Sep 17 00:00:00 2001 From: Nikita Tsukanov Date: Wed, 22 May 2019 12:14:37 +0300 Subject: [PATCH 1/2] Properly pass root object instance to templates, fixes #2147 #2527 --- .../XamlIl/Runtime/XamlIlRuntimeHelpers.cs | 18 +++++-- .../Avalonia.Markup.Xaml/XamlIl/xamlil.github | 2 +- .../Xaml/XamlIlTests.cs | 53 +++++++++++++++++++ 3 files changed, 68 insertions(+), 5 deletions(-) diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs b/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs index f91e221ac0..70b7fe6aec 100644 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Reflection; using Avalonia.Controls; using Avalonia.Data; +using Portable.Xaml; using Portable.Xaml.Markup; // ReSharper disable UnusedMember.Global // ReSharper disable UnusedParameter.Global @@ -17,19 +18,24 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime { var resourceNodes = provider.GetService().Parents .OfType().ToList(); - - return sp => builder(new DeferredParentServiceProvider(sp, resourceNodes)); + var rootObject = provider.GetService().RootObject; + return sp => builder(new DeferredParentServiceProvider(sp, resourceNodes, rootObject)); } - class DeferredParentServiceProvider : IAvaloniaXamlIlParentStackProvider, IServiceProvider + class DeferredParentServiceProvider : + IAvaloniaXamlIlParentStackProvider, + IServiceProvider, + IRootObjectProvider { private readonly IServiceProvider _parentProvider; private readonly List _parentResourceNodes; - public DeferredParentServiceProvider(IServiceProvider parentProvider, List parentResourceNodes) + public DeferredParentServiceProvider(IServiceProvider parentProvider, List parentResourceNodes, + object rootObject) { _parentProvider = parentProvider; _parentResourceNodes = parentResourceNodes; + RootObject = rootObject; } public IEnumerable Parents => GetParents(); @@ -46,8 +52,12 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime { if (serviceType == typeof(IAvaloniaXamlIlParentStackProvider)) return this; + if (serviceType == typeof(IRootObjectProvider)) + return this; return _parentProvider?.GetService(serviceType); } + + public object RootObject { get; } } diff --git a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github index 3b3c1f93a5..50920ece52 160000 --- a/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github +++ b/src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github @@ -1 +1 @@ -Subproject commit 3b3c1f93a566080d417b9782f9cc4ea67cd62344 +Subproject commit 50920ece52647b19760f65b417940da125101365 diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs index a584027768..175479e3ff 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs @@ -5,8 +5,12 @@ using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using Avalonia.Controls; +using Avalonia.Controls.Presenters; using Avalonia.Data.Converters; +using Avalonia.Input; +using Avalonia.Interactivity; using Avalonia.Media; +using Avalonia.Threading; using Avalonia.UnitTests; using Avalonia.VisualTree; using JetBrains.Annotations; @@ -117,6 +121,55 @@ namespace Avalonia.Markup.Xaml.UnitTests Assert.Equal(Brushes.Red.Color, ((ISolidColorBrush)canvas.Background).Color); } } + + [Fact] + public void Event_Handlers_Should_Work_For_Templates() + { + using (UnitTestApplication.Start(TestServices.StyledWindow)) + { + var w =new XamlIlBugTestsEventHandlerCodeBehind(); + w.ApplyTemplate(); + w.Show(); + + Dispatcher.UIThread.RunJobs(); + var itemsPresenter = ((ItemsControl)w.Content).GetVisualChildren().FirstOrDefault(); + var item = itemsPresenter + .GetVisualChildren().First() + .GetVisualChildren().First() + .GetVisualChildren().First(); + ((Control)item).RaiseEvent(new PointerPressedEventArgs {ClickCount = 20}); + Assert.Equal(20, w.Args.ClickCount); + } + } + } + + public class XamlIlBugTestsEventHandlerCodeBehind : Window + { + public PointerPressedEventArgs Args; + public void HandlePointerPressed(object sender, PointerPressedEventArgs args) + { + Args = args; + } + + public XamlIlBugTestsEventHandlerCodeBehind() + { + new AvaloniaXamlLoader().Load(@" + + + + +