diff --git a/src/Markup/Perspex.Markup.Xaml/Context/NameScopeWrapper.cs b/src/Markup/Perspex.Markup.Xaml/Context/NameScopeWrapper.cs index 4cb67ce912..2a5e46825a 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/NameScopeWrapper.cs +++ b/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; } diff --git a/src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs b/src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs index c771b30509..413df6c3ea 100644 --- a/src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs +++ b/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) { diff --git a/src/Markup/Perspex.Markup/ControlLocator.cs b/src/Markup/Perspex.Markup/ControlLocator.cs index 36330d89c5..c2c080137d 100644 --- a/src/Markup/Perspex.Markup/ControlLocator.cs +++ b/src/Markup/Perspex.Markup/ControlLocator.cs @@ -25,7 +25,7 @@ namespace Perspex.Markup var attached = Observable.FromEventPattern( 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( diff --git a/src/Perspex.Base/PerspexProperty.cs b/src/Perspex.Base/PerspexProperty.cs index 94f9baf5ba..ef06bf4326 100644 --- a/src/Perspex.Base/PerspexProperty.cs +++ b/src/Perspex.Base/PerspexProperty.cs @@ -56,7 +56,7 @@ namespace Perspex /// /// Gets the ID of the property. /// - private int _id; + private readonly int _id; /// /// Initializes a new instance of the class. diff --git a/src/Perspex.Controls/Button.cs b/src/Perspex.Controls/Button.cs index a1ca0e11a6..0bd29dbb64 100644 --- a/src/Perspex.Controls/Button.cs +++ b/src/Perspex.Controls/Button.cs @@ -134,18 +134,6 @@ namespace Perspex.Controls set { SetValue(IsDefaultProperty, value); } } - /// - protected override Size MeasureOverride(Size availableSize) - { - return base.MeasureOverride(availableSize); - } - - /// - protected override Size ArrangeOverride(Size finalSize) - { - return base.ArrangeOverride(finalSize); - } - /// protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { diff --git a/src/Perspex.Controls/Control.cs b/src/Perspex.Controls/Control.cs index b382e82675..f9d04faa73 100644 --- a/src/Perspex.Controls/Control.cs +++ b/src/Perspex.Controls/Control.cs @@ -71,6 +71,7 @@ namespace Perspex.Controls private DataTemplates _dataTemplates; private IControl _focusAdorner; private IPerspexList _logicalChildren; + private INameScope _nameScope; private Styles _styles; /// @@ -84,6 +85,14 @@ namespace Perspex.Controls PseudoClass(IsPointerOverProperty, ":pointerover"); } + /// + /// Initializes a new instance of the class. + /// + public Control() + { + _nameScope = this as INameScope; + } + /// /// Gets or sets the control's classes. /// @@ -376,11 +385,27 @@ namespace Perspex.Controls { base.OnAttachedToVisualTree(e); - IStyler styler = PerspexLocator.Current.GetService(); + if (_nameScope == null) + { + _nameScope = NameScope.GetNameScope(this) ?? ((Control)Parent)?._nameScope; + } + + if (Name != null) + { + _nameScope?.Register(Name, this); + } + + PerspexLocator.Current.GetService()?.ApplyStyles(this); + } + + /// + protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) + { + base.OnDetachedFromVisualTree(e); - if (styler != null) + if (Name != null) { - styler.ApplyStyles(this); + _nameScope?.Unregister(Name); } } diff --git a/src/Perspex.Controls/ControlExtensions.cs b/src/Perspex.Controls/ControlExtensions.cs index 08514258f7..6667810f24 100644 --- a/src/Perspex.Controls/ControlExtensions.cs +++ b/src/Perspex.Controls/ControlExtensions.cs @@ -59,14 +59,14 @@ namespace Perspex.Controls } /// - /// Finds the name scope for a control. + /// Finds the name scope for a control by searching up the logical tree. /// /// The control. /// The control's name scope, or null if not found. public static INameScope FindNameScope(this IControl control) { return control.GetSelfAndLogicalAncestors() - .OfType() + .OfType() .Select(x => (x as INameScope) ?? NameScope.GetNameScope(x)) .FirstOrDefault(x => x != null); } diff --git a/src/Perspex.Controls/Decorator.cs b/src/Perspex.Controls/Decorator.cs index a32e4364f5..1e1733a814 100644 --- a/src/Perspex.Controls/Decorator.cs +++ b/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); } } } diff --git a/src/Perspex.SceneGraph/INameScope.cs b/src/Perspex.Controls/INameScope.cs similarity index 98% rename from src/Perspex.SceneGraph/INameScope.cs rename to src/Perspex.Controls/INameScope.cs index 6e54c90afd..a6c115a4ec 100644 --- a/src/Perspex.SceneGraph/INameScope.cs +++ b/src/Perspex.Controls/INameScope.cs @@ -3,7 +3,7 @@ using System; -namespace Perspex +namespace Perspex.Controls { /// /// Defines a name scope. diff --git a/src/Perspex.SceneGraph/NameScope.cs b/src/Perspex.Controls/NameScope.cs similarity index 93% rename from src/Perspex.SceneGraph/NameScope.cs rename to src/Perspex.Controls/NameScope.cs index f4d0addc82..768e9de9dc 100644 --- a/src/Perspex.SceneGraph/NameScope.cs +++ b/src/Perspex.Controls/NameScope.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace Perspex +namespace Perspex.Controls { /// /// Implements a name scope. @@ -15,7 +15,7 @@ namespace Perspex /// Defines the NameScope attached property. /// public static readonly PerspexProperty NameScopeProperty = - PerspexProperty.RegisterAttached("NameScope"); + PerspexProperty.RegisterAttached("NameScope"); private readonly Dictionary _inner = new Dictionary(); @@ -34,7 +34,7 @@ namespace Perspex /// /// The visual. /// The value of the NameScope attached property. - public static INameScope GetNameScope(Visual visual) + public static INameScope GetNameScope(Control visual) { return visual.GetValue(NameScopeProperty); } @@ -44,7 +44,7 @@ namespace Perspex /// /// The visual. /// The value to set. - public static void SetNameScope(Visual visual, INameScope value) + public static void SetNameScope(Control visual, INameScope value) { visual.SetValue(NameScopeProperty, value); } diff --git a/src/Perspex.SceneGraph/NameScopeEventArgs.cs b/src/Perspex.Controls/NameScopeEventArgs.cs similarity index 94% rename from src/Perspex.SceneGraph/NameScopeEventArgs.cs rename to src/Perspex.Controls/NameScopeEventArgs.cs index 4d19082a24..254b13c4bd 100644 --- a/src/Perspex.SceneGraph/NameScopeEventArgs.cs +++ b/src/Perspex.Controls/NameScopeEventArgs.cs @@ -3,7 +3,7 @@ using System; -namespace Perspex +namespace Perspex.Controls { public class NameScopeEventArgs : EventArgs { diff --git a/src/Perspex.SceneGraph/NameScopeExtensions.cs b/src/Perspex.Controls/NameScopeExtensions.cs similarity index 98% rename from src/Perspex.SceneGraph/NameScopeExtensions.cs rename to src/Perspex.Controls/NameScopeExtensions.cs index 3e80f8e838..9053adebee 100644 --- a/src/Perspex.SceneGraph/NameScopeExtensions.cs +++ b/src/Perspex.Controls/NameScopeExtensions.cs @@ -4,7 +4,7 @@ using System; using System.Collections.Generic; -namespace Perspex +namespace Perspex.Controls { /// /// Extension methods for . diff --git a/src/Perspex.Controls/Perspex.Controls.csproj b/src/Perspex.Controls/Perspex.Controls.csproj index 80b1aba585..2682d76d16 100644 --- a/src/Perspex.Controls/Perspex.Controls.csproj +++ b/src/Perspex.Controls/Perspex.Controls.csproj @@ -43,6 +43,10 @@ + + + + diff --git a/src/Perspex.Controls/Presenters/ContentPresenter.cs b/src/Perspex.Controls/Presenters/ContentPresenter.cs index b2b2e6ff9f..46a57dd613 100644 --- a/src/Perspex.Controls/Presenters/ContentPresenter.cs +++ b/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); } diff --git a/src/Perspex.Controls/Primitives/TemplatedControl.cs b/src/Perspex.Controls/Primitives/TemplatedControl.cs index 170bfa6fa8..9e98ad154c 100644 --- a/src/Perspex.Controls/Primitives/TemplatedControl.cs +++ b/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 diff --git a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj index 2121be7bfc..776589de81 100644 --- a/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj +++ b/src/Perspex.SceneGraph/Perspex.SceneGraph.csproj @@ -56,7 +56,6 @@ - @@ -103,9 +102,6 @@ - - - diff --git a/src/Perspex.SceneGraph/Visual.cs b/src/Perspex.SceneGraph/Visual.cs index f559fd0f6e..14267ef132 100644 --- a/src/Perspex.SceneGraph/Visual.cs +++ b/src/Perspex.SceneGraph/Visual.cs @@ -407,12 +407,7 @@ namespace Perspex /// The event args. private static void AffectsRenderInvalidate(PerspexPropertyChangedEventArgs e) { - Visual visual = e.Sender as Visual; - - if (visual != null) - { - visual.InvalidateVisual(); - } + (e.Sender as Visual)?.InvalidateVisual(); } /// @@ -425,48 +420,8 @@ namespace Perspex /// 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; - } - - /// - /// Gets the for this element based on the - /// parent's args. - /// - /// The parent args. - /// The args for this element. - 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().FirstOrDefault(); + return root != null ? new VisualTreeAttachmentEventArgs(root) : null; } /// @@ -560,7 +515,14 @@ namespace Perspex /// The visual parent. 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); } /// @@ -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()) { - 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()) { - var ce = child.GetAttachmentEventArgs(e); - child.NotifyDetachedFromVisualTree(ce); + child.NotifyDetachedFromVisualTree(e); } } } diff --git a/src/Perspex.SceneGraph/VisualTreeAttachmentEventArgs.cs b/src/Perspex.SceneGraph/VisualTreeAttachmentEventArgs.cs index 41f37e26fc..b2df5a9a34 100644 --- a/src/Perspex.SceneGraph/VisualTreeAttachmentEventArgs.cs +++ b/src/Perspex.SceneGraph/VisualTreeAttachmentEventArgs.cs @@ -16,21 +16,14 @@ namespace Perspex /// Initializes a new instance of the class. /// /// The root visual. - /// The name scope. - public VisualTreeAttachmentEventArgs(IRenderRoot root, INameScope nameScope) + public VisualTreeAttachmentEventArgs(IRenderRoot root) { Root = root; - NameScope = nameScope; } /// /// Gets the root of the visual tree that the visual is being attached to or detached from. /// public IRenderRoot Root { get; } - - /// - /// Gets the element's name scope. - /// - public INameScope NameScope { get; } } } diff --git a/tests/Perspex.Controls.UnitTests/ControlTests_NameScope.cs b/tests/Perspex.Controls.UnitTests/ControlTests_NameScope.cs new file mode 100644 index 0000000000..2aa911b61a --- /dev/null +++ b/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(x => new ContentPresenter + { + Name = "PART_ContentPresenter", + [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty], + }); + } + + public event EventHandler Registered + { + add { _nameScope.Registered += value; } + remove { _nameScope.Registered -= value; } + } + + public event EventHandler 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); + } + } + } +} diff --git a/tests/Perspex.SceneGraph.UnitTests/NameScopeTests.cs b/tests/Perspex.Controls.UnitTests/NameScopeTests.cs similarity index 97% rename from tests/Perspex.SceneGraph.UnitTests/NameScopeTests.cs rename to tests/Perspex.Controls.UnitTests/NameScopeTests.cs index a774e6884d..da4079f3c1 100644 --- a/tests/Perspex.SceneGraph.UnitTests/NameScopeTests.cs +++ b/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 { diff --git a/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj b/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj index c19e639895..745556a791 100644 --- a/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj +++ b/tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj @@ -81,12 +81,14 @@ + + diff --git a/tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs b/tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs index 1d39e8d443..d0f0547854 100644 --- a/tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs +++ b/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] diff --git a/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj b/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj index f5cfe531c9..d161b1264f 100644 --- a/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj +++ b/tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj @@ -72,7 +72,6 @@ - @@ -160,4 +159,4 @@ --> - + \ No newline at end of file diff --git a/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs b/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs index 62bc782b78..99a1fd0d4a 100644 --- a/tests/Perspex.SceneGraph.UnitTests/TestRoot.cs +++ b/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 INameScope.Registered - { - add { _nameScope.Registered += value; } - remove { _nameScope.Registered -= value; } - } - - public event EventHandler 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); - } } } diff --git a/tests/Perspex.SceneGraph.UnitTests/VisualTests.cs b/tests/Perspex.SceneGraph.UnitTests/VisualTests.cs index 7756130c20..f4785b66c1 100644 --- a/tests/Perspex.SceneGraph.UnitTests/VisualTests.cs +++ b/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")); - } } }