From 2bd26bd9b8006695451aa6470448699cd9e78b40 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 26 Oct 2017 00:57:41 +0200 Subject: [PATCH 1/2] Added failing test for #1245. --- .../Primitives/PopupTests.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs index ccbf04533d..85a450e1dc 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs @@ -249,6 +249,37 @@ namespace Avalonia.Controls.UnitTests.Primitives } } + [Fact] + public void DataContextBeginUpdate_Should_Not_Be_Called_For_Controls_That_Dont_Inherit() + { + using (CreateServices()) + { + TestControl child; + var popup = new Popup + { + Child = child = new TestControl(), + DataContext = "foo", + }; + + var beginCalled = false; + child.DataContextBeginUpdate += (s, e) => beginCalled = true; + + // Test for #1245. Here, the child's logical parent is the popup but it's not yet + // attached to a visual tree because the popup hasn't been opened. + Assert.Same(popup, ((ILogical)child).LogicalParent); + Assert.Same(popup, child.InheritanceParent); + Assert.Null(child.GetVisualRoot()); + + popup.Open(); + + // #1245 was caused by the fact that DataContextBeginUpdate was called on `target` + // when the PopupRoot was created, even though PopupRoot isn't the + // InheritanceParent of child. + Assert.False(beginCalled); + } + } + + private static IDisposable CreateServices() { var result = AvaloniaLocator.EnterScope(); @@ -304,5 +335,18 @@ namespace Avalonia.Controls.UnitTests.Primitives private class PopupContentControl : ContentControl { } + + private class TestControl : Decorator + { + public event EventHandler DataContextBeginUpdate; + + public new IAvaloniaObject InheritanceParent => base.InheritanceParent; + + protected override void OnDataContextBeginUpdate() + { + DataContextBeginUpdate?.Invoke(this, EventArgs.Empty); + base.OnDataContextBeginUpdate(); + } + } } } From 6421d422cbf884a265e00a92c84a56a00c9cae62 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 26 Oct 2017 01:01:07 +0200 Subject: [PATCH 2/2] Fix data context change notification. Don't notify a non-inheritance child that the data context has begun changing, because it won't receive the accompanying end change notification. Fixes #1245. --- src/Avalonia.Controls/Control.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Controls/Control.cs b/src/Avalonia.Controls/Control.cs index a7aafbf6e8..d4777b2f8a 100644 --- a/src/Avalonia.Controls/Control.cs +++ b/src/Avalonia.Controls/Control.cs @@ -774,7 +774,9 @@ namespace Avalonia.Controls foreach (var child in control.LogicalChildren) { - if (child is Control c && !c.IsSet(DataContextProperty)) + if (child is Control c && + c.InheritanceParent == control && + !c.IsSet(DataContextProperty)) { DataContextNotifying(c, notifying); }