From ceece5802bb0f2e4e2153653b7403c0c73979060 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Sun, 29 Nov 2015 10:22:38 +0100 Subject: [PATCH] Correctly track removal in ControlLocator. Fixes #323. --- src/Markup/Perspex.Markup/ControlLocator.cs | 6 ++-- src/Perspex.Controls/NameScope.cs | 2 +- .../ControlLocatorTests.cs | 30 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/Markup/Perspex.Markup/ControlLocator.cs b/src/Markup/Perspex.Markup/ControlLocator.cs index c2c080137d..4887de8a15 100644 --- a/src/Markup/Perspex.Markup/ControlLocator.cs +++ b/src/Markup/Perspex.Markup/ControlLocator.cs @@ -45,10 +45,12 @@ namespace Perspex.Markup .OfType(); var unregistered = Observable.FromEventPattern( x => nameScope.Unregistered += x, - x => nameScope.Unregistered -= x); + x => nameScope.Unregistered -= x) + .Where(x => x.EventArgs.Name == name) + .Select(_ => (IControl)null); return registered .StartWith(nameScope.Find(name)) - .TakeUntil(unregistered); + .Merge(unregistered); } else { diff --git a/src/Perspex.Controls/NameScope.cs b/src/Perspex.Controls/NameScope.cs index 768e9de9dc..ab64733a4b 100644 --- a/src/Perspex.Controls/NameScope.cs +++ b/src/Perspex.Controls/NameScope.cs @@ -102,7 +102,7 @@ namespace Perspex.Controls if (_inner.TryGetValue(name, out element)) { _inner.Remove(name); - Registered?.Invoke(this, new NameScopeEventArgs(name, element)); + Unregistered?.Invoke(this, new NameScopeEventArgs(name, element)); } } } diff --git a/tests/Perspex.Markup.UnitTests/ControlLocatorTests.cs b/tests/Perspex.Markup.UnitTests/ControlLocatorTests.cs index 14286479c2..19dbe5200b 100644 --- a/tests/Perspex.Markup.UnitTests/ControlLocatorTests.cs +++ b/tests/Perspex.Markup.UnitTests/ControlLocatorTests.cs @@ -71,6 +71,36 @@ namespace Perspex.Markup.UnitTests Assert.Equal(0, root.NameScopeUnregisteredSubscribers); } + [Fact] + public void Track_By_Name_Should_Track_Removal_And_Readd() + { + StackPanel panel; + TextBlock target; + TextBlock relativeTo; + + var root = new TestRoot + { + Child = panel = new StackPanel + { + Children = new Controls.Controls + { + (target = new TextBlock { Name = "target" }), + (relativeTo = new TextBlock { Name = "start" }), + } + } + }; + + var locator = ControlLocator.Track(relativeTo, "target"); + var result = new List(); + locator.Subscribe(x => result.Add(x)); + + var other = new TextBlock { Name = "target" }; + panel.Children.Remove(target); + panel.Children.Add(other); + + Assert.Equal(new[] { target, null, other }, result); + } + [Fact] public void Track_By_Name_Should_Find_Control_When_Tree_Changed() {