Browse Source

Fixed name scopes.

Controls were being registered with the nearest name scope on the visual
tree, whereas they should be registered by traversing the logical tree.
Steven Kirk 10 years ago
parent
commit
9eb54f59d2

+ 2 - 2
src/Markup/Perspex.Markup.Xaml/Context/NameScopeWrapper.cs

@@ -5,9 +5,9 @@ namespace Perspex.Markup.Xaml.Context
 {
     internal class NameScopeWrapper : OmniXaml.INameScope
     {
-        private Perspex.INameScope _inner;
+        private readonly Perspex.Controls.INameScope _inner;
 
-        public NameScopeWrapper(Perspex.INameScope inner)
+        public NameScopeWrapper(Perspex.Controls.INameScope inner)
         {
             _inner = inner;
         }

+ 5 - 5
src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs

@@ -5,7 +5,7 @@ using System;
 using System.Reflection;
 using OmniXaml;
 using OmniXaml.Typing;
-using Perspex.Markup.Xaml.Data;
+using Perspex.Controls;
 
 namespace Perspex.Markup.Xaml.Context
 {
@@ -20,15 +20,15 @@ namespace Perspex.Markup.Xaml.Context
 
         public override OmniXaml.INameScope GetNamescope(object instance)
         {
-            var result = this.UnderlyingType as OmniXaml.INameScope;
+            var result = instance as OmniXaml.INameScope;
 
             if (result == null)
             {
-                var visual = instance as Visual;
+                var control = instance as Control;
 
-                if (visual != null)
+                if (control != null)
                 {
-                    var perspexNs = (instance as Perspex.INameScope) ?? NameScope.GetNameScope(visual);
+                    var perspexNs = (instance as Perspex.Controls.INameScope) ?? NameScope.GetNameScope(control);
 
                     if (perspexNs != null)
                     {

+ 1 - 1
src/Markup/Perspex.Markup/ControlLocator.cs

@@ -25,7 +25,7 @@ namespace Perspex.Markup
             var attached = Observable.FromEventPattern<VisualTreeAttachmentEventArgs>(
                 x => relativeTo.AttachedToVisualTree += x,
                 x => relativeTo.DetachedFromVisualTree += x)
-                .Select(x => x.EventArgs.NameScope)
+                .Select(x => ((IControl)x.Sender).FindNameScope())
                 .StartWith(relativeTo.FindNameScope());
 
             var detached = Observable.FromEventPattern<VisualTreeAttachmentEventArgs>(

+ 1 - 1
src/Perspex.Base/PerspexProperty.cs

@@ -56,7 +56,7 @@ namespace Perspex
         /// <summary>
         /// Gets the ID of the property.
         /// </summary>
-        private int _id;
+        private readonly int _id;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="PerspexProperty"/> class.

+ 0 - 12
src/Perspex.Controls/Button.cs

@@ -134,18 +134,6 @@ namespace Perspex.Controls
             set { SetValue(IsDefaultProperty, value); }
         }
 
-        /// <inheritdoc/>
-        protected override Size MeasureOverride(Size availableSize)
-        {
-            return base.MeasureOverride(availableSize);
-        }
-
-        /// <inheritdoc/>
-        protected override Size ArrangeOverride(Size finalSize)
-        {
-            return base.ArrangeOverride(finalSize);
-        }
-
         /// <inheritdoc/>
         protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
         {

+ 28 - 3
src/Perspex.Controls/Control.cs

@@ -71,6 +71,7 @@ namespace Perspex.Controls
         private DataTemplates _dataTemplates;
         private IControl _focusAdorner;
         private IPerspexList<ILogical> _logicalChildren;
+        private INameScope _nameScope;
         private Styles _styles;
 
         /// <summary>
@@ -84,6 +85,14 @@ namespace Perspex.Controls
             PseudoClass(IsPointerOverProperty, ":pointerover");
         }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="Control"/> class.
+        /// </summary>
+        public Control()
+        {
+            _nameScope = this as INameScope;
+        }
+
         /// <summary>
         /// Gets or sets the control's classes.
         /// </summary>
@@ -376,11 +385,27 @@ namespace Perspex.Controls
         {
             base.OnAttachedToVisualTree(e);
 
-            IStyler styler = PerspexLocator.Current.GetService<IStyler>();
+            if (_nameScope == null)
+            {
+                _nameScope = NameScope.GetNameScope(this) ?? ((Control)Parent)?._nameScope;
+            }
+
+            if (Name != null)
+            {
+                _nameScope?.Register(Name, this);
+            }
+
+            PerspexLocator.Current.GetService<IStyler>()?.ApplyStyles(this);
+        }
+
+        /// <inheritdoc/>
+        protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
+        {
+            base.OnDetachedFromVisualTree(e);
 
-            if (styler != null)
+            if (Name != null)
             {
-                styler.ApplyStyles(this);
+                _nameScope?.Unregister(Name);
             }
         }
 

+ 2 - 2
src/Perspex.Controls/ControlExtensions.cs

@@ -59,14 +59,14 @@ namespace Perspex.Controls
         }
 
         /// <summary>
-        /// Finds the name scope for a control.
+        /// Finds the name scope for a control by searching up the logical tree.
         /// </summary>
         /// <param name="control">The control.</param>
         /// <returns>The control's name scope, or null if not found.</returns>
         public static INameScope FindNameScope(this IControl control)
         {
             return control.GetSelfAndLogicalAncestors()
-                .OfType<Visual>()
+                .OfType<Control>()
                 .Select(x => (x as INameScope) ?? NameScope.GetNameScope(x))
                 .FirstOrDefault(x => x != null);
         }

+ 1 - 1
src/Perspex.Controls/Decorator.cs

@@ -98,9 +98,9 @@ namespace Perspex.Controls
 
             if (newChild != null)
             {
+                ((ISetLogicalParent)newChild).SetParent(this);
                 AddVisualChild(newChild);
                 LogicalChildren.Add(newChild);
-                ((ISetLogicalParent)newChild).SetParent(this);
             }
         }
     }

+ 1 - 1
src/Perspex.SceneGraph/INameScope.cs → src/Perspex.Controls/INameScope.cs

@@ -3,7 +3,7 @@
 
 using System;
 
-namespace Perspex
+namespace Perspex.Controls
 {
     /// <summary>
     /// Defines a name scope.

+ 4 - 4
src/Perspex.SceneGraph/NameScope.cs → src/Perspex.Controls/NameScope.cs

@@ -4,7 +4,7 @@
 using System;
 using System.Collections.Generic;
 
-namespace Perspex
+namespace Perspex.Controls
 {
     /// <summary>
     /// Implements a name scope.
@@ -15,7 +15,7 @@ namespace Perspex
         /// Defines the NameScope attached property.
         /// </summary>
         public static readonly PerspexProperty<INameScope> NameScopeProperty =
-            PerspexProperty.RegisterAttached<NameScope, Visual, INameScope>("NameScope");
+            PerspexProperty.RegisterAttached<NameScope, Control, INameScope>("NameScope");
 
         private readonly Dictionary<string, object> _inner = new Dictionary<string, object>();
 
@@ -34,7 +34,7 @@ namespace Perspex
         /// </summary>
         /// <param name="visual">The visual.</param>
         /// <returns>The value of the NameScope attached property.</returns>
-        public static INameScope GetNameScope(Visual visual)
+        public static INameScope GetNameScope(Control visual)
         {
             return visual.GetValue(NameScopeProperty);
         }
@@ -44,7 +44,7 @@ namespace Perspex
         /// </summary>
         /// <param name="visual">The visual.</param>
         /// <param name="value">The value to set.</param>
-        public static void SetNameScope(Visual visual, INameScope value)
+        public static void SetNameScope(Control visual, INameScope value)
         {
             visual.SetValue(NameScopeProperty, value);
         }

+ 1 - 1
src/Perspex.SceneGraph/NameScopeEventArgs.cs → src/Perspex.Controls/NameScopeEventArgs.cs

@@ -3,7 +3,7 @@
 
 using System;
 
-namespace Perspex
+namespace Perspex.Controls
 {
     public class NameScopeEventArgs : EventArgs
     {

+ 1 - 1
src/Perspex.SceneGraph/NameScopeExtensions.cs → src/Perspex.Controls/NameScopeExtensions.cs

@@ -4,7 +4,7 @@
 using System;
 using System.Collections.Generic;
 
-namespace Perspex
+namespace Perspex.Controls
 {
     /// <summary>
     /// Extension methods for <see cref="INameScope"/>.

+ 4 - 0
src/Perspex.Controls/Perspex.Controls.csproj

@@ -43,6 +43,10 @@
     </Compile>
     <Compile Include="DockPanel.cs" />
     <Compile Include="HotkeyManager.cs" />
+    <Compile Include="INameScope.cs" />
+    <Compile Include="NameScope.cs" />
+    <Compile Include="NameScopeEventArgs.cs" />
+    <Compile Include="NameScopeExtensions.cs" />
     <Compile Include="Platform\ITopLevelRenderer.cs" />
     <Compile Include="Platform\IWindowingPlatform.cs" />
     <Compile Include="Platform\PlatformManager.cs" />

+ 2 - 3
src/Perspex.Controls/Presenters/ContentPresenter.cs

@@ -106,8 +106,8 @@ namespace Perspex.Controls.Presenters
 
             if (old != null)
             {
-                logicalChildren.Remove(old);
                 ((ISetLogicalParent)old).SetParent(null);
+                logicalChildren.Remove(old);
                 ClearVisualChildren();
             }
 
@@ -120,13 +120,12 @@ namespace Perspex.Controls.Presenters
                     result.DataContext = content;
                 }
 
-                AddVisualChild(result);
-
                 if (result.Parent == null)
                 {
                     ((ISetLogicalParent)result).SetParent((ILogical)logicalHost ?? this);
                 }
 
+                AddVisualChild(result);
                 logicalChildren.Remove(old);
                 logicalChildren.Add(result);
             }

+ 1 - 1
src/Perspex.Controls/Primitives/TemplatedControl.cs

@@ -196,7 +196,7 @@ namespace Perspex.Controls.Primitives
 
                     var child = Template.Build(this);
                     var nameScope = new NameScope();
-                    NameScope.SetNameScope((Visual)child, nameScope);
+                    NameScope.SetNameScope((Control)child, nameScope);
 
                     // We need to call SetTemplatedParentAndApplyChildTemplates twice - once
                     // before the controls are added to the visual tree so that the logical

+ 0 - 4
src/Perspex.SceneGraph/Perspex.SceneGraph.csproj

@@ -56,7 +56,6 @@
     <Compile Include="Animation\CrossFade.cs" />
     <Compile Include="Animation\IPageTransition.cs" />
     <Compile Include="INamed.cs" />
-    <Compile Include="INameScope.cs" />
     <Compile Include="Matrix.cs" />
     <Compile Include="Media\AlignmentY.cs" />
     <Compile Include="Media\AlignmentX.cs" />
@@ -103,9 +102,6 @@
     <Compile Include="Media\TileBrush.cs" />
     <Compile Include="Media\ImageBush.cs" />
     <Compile Include="Media\VisualBrush.cs" />
-    <Compile Include="NameScopeEventArgs.cs" />
-    <Compile Include="NameScopeExtensions.cs" />
-    <Compile Include="NameScope.cs" />
     <Compile Include="RelativePoint.cs" />
     <Compile Include="Platform\IFormattedTextImpl.cs" />
     <Compile Include="Platform\IBitmapImpl.cs" />

+ 22 - 65
src/Perspex.SceneGraph/Visual.cs

@@ -407,12 +407,7 @@ namespace Perspex
         /// <param name="e">The event args.</param>
         private static void AffectsRenderInvalidate(PerspexPropertyChangedEventArgs e)
         {
-            Visual visual = e.Sender as Visual;
-
-            if (visual != null)
-            {
-                visual.InvalidateVisual();
-            }
+            (e.Sender as Visual)?.InvalidateVisual();
         }
 
         /// <summary>
@@ -425,48 +420,8 @@ namespace Perspex
         /// </returns>
         private VisualTreeAttachmentEventArgs GetAttachmentEventArgs()
         {
-            var e = (IVisual)this;
-            IRenderRoot root = null;
-            INameScope nameScope = null;
-
-            while (e != null)
-            {
-                if (nameScope == null)
-                {
-                    nameScope = e as INameScope ?? NameScope.GetNameScope((Visual)e);
-                }
-
-                root = e as IRenderRoot;
-
-                if (root != null)
-                {
-                    return new VisualTreeAttachmentEventArgs(root, nameScope);
-                }
-
-                e = e.VisualParent;
-            }
-
-            return null;
-        }
-
-        /// <summary>
-        /// Gets the <see cref="VisualTreeAttachmentEventArgs"/> for this element based on the 
-        /// parent's args.
-        /// </summary>
-        /// <param name="e">The parent args.</param>
-        /// <returns>The args for this element.</returns>
-        private VisualTreeAttachmentEventArgs GetAttachmentEventArgs(VisualTreeAttachmentEventArgs e)
-        {
-            var childNameScope = (this as INameScope) ?? NameScope.GetNameScope(this);
-
-            if (childNameScope != null)
-            {
-                return new VisualTreeAttachmentEventArgs(e.Root, childNameScope);
-            }
-            else
-            {
-                return e;
-            }
+            var root = this.GetSelfAndVisualAncestors().OfType<IRenderRoot>().FirstOrDefault();
+            return root != null ? new VisualTreeAttachmentEventArgs(root) : null;
         }
 
         /// <summary>
@@ -560,7 +515,14 @@ namespace Perspex
         /// <param name="value">The visual parent.</param>
         private void SetVisualParent(Visual value)
         {
-            if (_visualParent != value)
+            if (_visualParent == value)
+            {
+                return;
+            }
+            
+            var old = _visualParent;
+
+            if (_isAttachedToVisualTree)
             {
                 var oldArgs = GetAttachmentEventArgs();
 
@@ -570,16 +532,23 @@ namespace Perspex
                 {
                     NotifyDetachedFromVisualTree(oldArgs);
                 }
+            }
+            else
+            {
+                _visualParent = value;
+            }
 
+            if (_visualParent is IRenderRoot || _visualParent?.IsAttachedToVisualTree == true)
+            {
                 var newArgs = GetAttachmentEventArgs();
 
                 if (newArgs != null)
                 {
                     NotifyAttachedToVisualTree(newArgs);
                 }
-
-                RaisePropertyChanged(VisualParentProperty, oldArgs, value, BindingPriority.LocalValue);
             }
+
+            RaisePropertyChanged(VisualParentProperty, old, value, BindingPriority.LocalValue);
         }
 
         /// <summary>
@@ -622,19 +591,13 @@ namespace Perspex
 
             _isAttachedToVisualTree = true;
 
-            if (Name != null && e.NameScope != null)
-            {
-                e.NameScope.Register(Name, this);
-            }
-
             OnAttachedToVisualTree(e);
 
             if (_visualChildren != null)
             {
                 foreach (Visual child in _visualChildren.OfType<Visual>())
                 {
-                    var ce = child.GetAttachmentEventArgs(e);
-                    child.NotifyAttachedToVisualTree(ce);
+                    child.NotifyAttachedToVisualTree(e);
                 }
             }
         }
@@ -648,11 +611,6 @@ namespace Perspex
         {
             _visualLogger.Verbose("Detached from visual tree");
 
-            if (Name != null && e.NameScope != null)
-            {
-                e.NameScope.Unregister(Name);
-            }
-
             _isAttachedToVisualTree = false;
             OnDetachedFromVisualTree(e);
 
@@ -660,8 +618,7 @@ namespace Perspex
             {
                 foreach (Visual child in _visualChildren.OfType<Visual>())
                 {
-                    var ce = child.GetAttachmentEventArgs(e);
-                    child.NotifyDetachedFromVisualTree(ce);
+                    child.NotifyDetachedFromVisualTree(e);
                 }
             }
         }

+ 1 - 8
src/Perspex.SceneGraph/VisualTreeAttachmentEventArgs.cs

@@ -16,21 +16,14 @@ namespace Perspex
         /// Initializes a new instance of the <see cref="VisualTreeAttachmentEventArgs"/> class.
         /// </summary>
         /// <param name="root">The root visual.</param>
-        /// <param name="nameScope">The name scope.</param>
-        public VisualTreeAttachmentEventArgs(IRenderRoot root, INameScope nameScope)
+        public VisualTreeAttachmentEventArgs(IRenderRoot root)
         {
             Root = root;
-            NameScope = nameScope;
         }
 
         /// <summary>
         /// Gets the root of the visual tree that the visual is being attached to or detached from.
         /// </summary>
         public IRenderRoot Root { get; }
-
-        /// <summary>
-        /// Gets the element's name scope.
-        /// </summary>
-        public INameScope NameScope { get; }
     }
 }

+ 125 - 0
tests/Perspex.Controls.UnitTests/ControlTests_NameScope.cs

@@ -0,0 +1,125 @@
+// Copyright (c) The Perspex Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using Perspex.Controls.Presenters;
+using Perspex.Controls.Templates;
+using Perspex.Rendering;
+using Xunit;
+
+namespace Perspex.Controls.UnitTests
+{
+    public class ControlTests_NameScope
+    {
+        [Fact]
+        public void Controls_Should_Register_With_NameScope()
+        {
+            var root = new TestRoot
+            {
+                Content = new Border
+                {
+                    Name = "foo",
+                    Child = new Border
+                    {
+                        Name = "bar",
+                    }
+                }
+            };
+
+            root.ApplyTemplate();
+
+            Assert.Same(root.Find("foo"), root.Content);
+            Assert.Same(root.Find("bar"), ((Border)root.Content).Child);
+        }
+
+        [Fact]
+        public void Control_Should_Unregister_With_NameScope()
+        {
+            var root = new TestRoot
+            {
+                Content = new Border
+                {
+                    Name = "foo",
+                    Child = new Border
+                    {
+                        Name = "bar",
+                    }
+                }
+            };
+
+            root.ApplyTemplate();
+            root.Content = null;
+            root.Presenter.ApplyTemplate();
+
+            Assert.Null(root.Find("foo"));
+            Assert.Null(root.Find("bar"));
+        }
+
+        [Fact]
+        public void Control_Should_Not_Register_With_Template_NameScope()
+        {
+            var root = new TestRoot
+            {
+                Content = new Border
+                {
+                    Name = "foo",
+                }
+            };
+
+            root.ApplyTemplate();
+
+            Assert.Null(NameScope.GetNameScope(root.Presenter).Find("foo"));
+        }
+
+        private class TestRoot : ContentControl, IRenderRoot, INameScope
+        {
+            private readonly NameScope _nameScope = new NameScope();
+
+            public TestRoot()
+            {
+                Template = new FuncControlTemplate<TestRoot>(x => new ContentPresenter
+                {
+                    Name = "PART_ContentPresenter",
+                    [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
+                });
+            }
+
+            public event EventHandler<NameScopeEventArgs> Registered
+            {
+                add { _nameScope.Registered += value; }
+                remove { _nameScope.Registered -= value; }
+            }
+
+            public event EventHandler<NameScopeEventArgs> Unregistered
+            {
+                add { _nameScope.Unregistered += value; }
+                remove { _nameScope.Unregistered -= value; }
+            }
+
+            public IRenderQueueManager RenderQueueManager
+            {
+                get { throw new NotImplementedException(); }
+            }
+
+            public Point TranslatePointToScreen(Point p)
+            {
+                throw new NotImplementedException();
+            }
+
+            public void Register(string name, object element)
+            {
+                _nameScope.Register(name, element);
+            }
+
+            public object Find(string name)
+            {
+                return _nameScope.Find(name);
+            }
+
+            public void Unregister(string name)
+            {
+                _nameScope.Unregister(name);
+            }
+        }
+    }
+}

+ 1 - 1
tests/Perspex.SceneGraph.UnitTests/NameScopeTests.cs → tests/Perspex.Controls.UnitTests/NameScopeTests.cs

@@ -4,7 +4,7 @@
 using System;
 using Xunit;
 
-namespace Perspex.SceneGraph.UnitTests
+namespace Perspex.Controls.UnitTests
 {
     public class NameScopeTests
     {

+ 2 - 0
tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj

@@ -81,12 +81,14 @@
     <Otherwise />
   </Choose>
   <ItemGroup>
+    <Compile Include="ControlTests_NameScope.cs" />
     <Compile Include="Generators\ItemContainerGeneratorTests.cs" />
     <Compile Include="Generators\ItemContainerGeneratorTypedTests.cs" />
     <Compile Include="GridLengthTests.cs" />
     <Compile Include="ContentPresenterTests.cs" />
     <Compile Include="BorderTests.cs" />
     <Compile Include="ListBoxTests_Single.cs" />
+    <Compile Include="NameScopeTests.cs" />
     <Compile Include="Primitives\SelectingItemsControlTests_Multiple.cs" />
     <Compile Include="WindowingPlatformMock.cs" />
     <Compile Include="TreeViewTests.cs" />

+ 1 - 1
tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs

@@ -70,7 +70,7 @@ namespace Perspex.Controls.UnitTests.Primitives
 
             target.ApplyTemplate();
 
-            Assert.NotNull(NameScope.GetNameScope((Visual)target.GetVisualChildren().Single()));
+            Assert.NotNull(NameScope.GetNameScope((Control)target.GetVisualChildren().Single()));
         }
 
         [Fact]

+ 1 - 2
tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj

@@ -72,7 +72,6 @@
     <Otherwise />
   </Choose>
   <ItemGroup>
-    <Compile Include="NameScopeTests.cs" />
     <Compile Include="RelativeRectComparer.cs" />
     <Compile Include="RelativeRectTests.cs" />
     <Compile Include="ThicknessTests.cs" />
@@ -160,4 +159,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
+</Project>

+ 1 - 30
tests/Perspex.SceneGraph.UnitTests/TestRoot.cs

@@ -7,22 +7,8 @@ using Perspex.Rendering;
 
 namespace Perspex.SceneGraph.UnitTests
 {
-    public class TestRoot : TestVisual, IRenderRoot, INameScope
+    public class TestRoot : TestVisual, IRenderRoot
     {
-        private NameScope _nameScope = new NameScope();
-
-        event EventHandler<NameScopeEventArgs> INameScope.Registered
-        {
-            add { _nameScope.Registered += value; }
-            remove { _nameScope.Registered -= value; }
-        }
-
-        public event EventHandler<NameScopeEventArgs> Unregistered
-        {
-            add { _nameScope.Unregistered += value; }
-            remove { _nameScope.Unregistered -= value; }
-        }
-
         public IRenderTarget RenderTarget
         {
             get { throw new NotImplementedException(); }
@@ -37,20 +23,5 @@ namespace Perspex.SceneGraph.UnitTests
         {
             throw new NotImplementedException();
         }
-
-        public void Register(string name, object element)
-        {
-            _nameScope.Register(name, element);
-        }
-
-        public object Find(string name)
-        {
-            return _nameScope.Find(name);
-        }
-
-        public void Unregister(string name)
-        {
-            _nameScope.Unregister(name);
-        }
     }
 }

+ 0 - 50
tests/Perspex.SceneGraph.UnitTests/VisualTests.cs

@@ -121,55 +121,5 @@ namespace Perspex.SceneGraph.UnitTests
             Assert.True(called1);
             Assert.True(called2);
         }
-
-        [Fact]
-        public void Controls_Should_Add_Themselves_To_Root_NameScope()
-        {
-            var child2 = new TestVisual { Name = "bar" };
-            var child1 = new TestVisual { Name = "foo", Child = child2 };
-            var root = new TestRoot { Child = child1 };
-
-            Assert.Same(child1, root.Find("foo"));
-            Assert.Same(child2, root.Find("bar"));
-        }
-
-        [Fact]
-        public void Controls_Should_Add_Themselves_To_NameScopes_In_Attached_Property()
-        {
-            var child2 = new TestVisual { Name = "bar", [NameScope.NameScopeProperty] = new NameScope() };
-            var child1 = new TestVisual { Name = "foo", Child = child2};
-            var root = new TestRoot { Child = child1 };
-
-            Assert.Same(child1, root.Find("foo"));
-            Assert.Null(root.Find("bar"));
-            Assert.Same(child2, NameScope.GetNameScope(child2).Find("bar"));
-        }
-
-        [Fact]
-        public void Controls_Should_Remove_Themselves_From_Root_NameScope()
-        {
-            var child2 = new TestVisual { Name = "bar" };
-            var child1 = new TestVisual { Name = "foo", Child = child2 };
-            var root = new TestRoot { Child = child1 };
-
-            root.Child = null;
-
-            Assert.Null(root.Find("foo"));
-            Assert.Null(root.Find("bar"));
-        }
-
-        [Fact]
-        public void Controls_Should_Remove_Themselves_From_NameScopes_In_Attached_Property()
-        {
-            var child2 = new TestVisual { Name = "bar" };
-            var child1 = new TestVisual { Name = "foo", Child = child2,[NameScope.NameScopeProperty] = new NameScope() };
-            var root = new TestRoot { Child = child1 };
-
-            root.Child = null;
-
-            Assert.Null(root.Find("foo"));
-            Assert.Null(root.Find("bar"));
-            Assert.Null(NameScope.GetNameScope(child1).Find("bar"));
-        }
     }
 }