Browse Source

Correctly track removal in ControlLocator.

Fixes #323.
Steven Kirk 10 years ago
parent
commit
ceece5802b

+ 4 - 2
src/Markup/Perspex.Markup/ControlLocator.cs

@@ -45,10 +45,12 @@ namespace Perspex.Markup
                         .OfType<IControl>();
                     var unregistered = Observable.FromEventPattern<NameScopeEventArgs>(
                         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<IControl>(name))
-                        .TakeUntil(unregistered);
+                        .Merge(unregistered);
                 }
                 else
                 {

+ 1 - 1
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));
             }
         }
     }

+ 30 - 0
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<IControl>();
+            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()
         {