Bladeren bron

Manually handle name scope registrations

Nikita Tsukanov 6 jaren geleden
bovenliggende
commit
fa55755b71
78 gewijzigde bestanden met toevoegingen van 537 en 602 verwijderingen
  1. 1 1
      src/Avalonia.Controls/AutoCompleteBox.cs
  2. 1 20
      src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
  3. 0 19
      src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
  4. 11 3
      src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs
  5. 0 6
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  6. 6 24
      src/Avalonia.Controls/Primitives/TemplatedControl.cs
  7. 2 2
      src/Avalonia.Controls/Templates/FuncControlTemplate.cs
  8. 3 3
      src/Avalonia.Controls/Templates/FuncControlTemplate`2.cs
  9. 4 4
      src/Avalonia.Controls/Templates/FuncDataTemplate.cs
  10. 22 4
      src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs
  11. 24 0
      src/Avalonia.Controls/Templates/FuncTemplateNameScopeExtensions.cs
  12. 9 4
      src/Avalonia.Controls/Templates/FuncTemplate`2.cs
  13. 2 2
      src/Avalonia.Controls/Templates/FuncTreeDataTemplate.cs
  14. 13 2
      src/Avalonia.Controls/Templates/FuncTreeDataTemplate`1.cs
  15. 1 33
      src/Avalonia.Controls/UserControl.cs
  16. 1 33
      src/Avalonia.Controls/Window.cs
  17. 2 2
      src/Avalonia.ReactiveUI/AutoDataTemplateBindingHook.cs
  18. 15 0
      src/Avalonia.Styling/Controls/NameScope.cs
  19. 41 0
      src/Avalonia.Styling/Controls/NameScopeExtensions.cs
  20. 0 21
      src/Avalonia.Styling/StyledElement.cs
  21. 0 1
      src/Avalonia.Styling/Styling/Setter.cs
  22. 1 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs
  23. 32 37
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs
  24. 12 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs
  25. 1 0
      src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs
  26. 1 1
      src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github
  27. 8 0
      src/Markup/Avalonia.Markup.Xaml/XamlTypes.cs
  28. 5 5
      tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
  29. 2 2
      tests/Avalonia.Controls.UnitTests/CarouselTests.cs
  30. 5 5
      tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs
  31. 6 6
      tests/Avalonia.Controls.UnitTests/ContentControlTests.cs
  32. 6 6
      tests/Avalonia.Controls.UnitTests/DatePickerTests.cs
  33. 12 9
      tests/Avalonia.Controls.UnitTests/GridSplitterTests.cs
  34. 3 3
      tests/Avalonia.Controls.UnitTests/HeaderedItemsControlTests .cs
  35. 5 5
      tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs
  36. 15 15
      tests/Avalonia.Controls.UnitTests/ListBoxTests.cs
  37. 7 6
      tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs
  38. 9 8
      tests/Avalonia.Controls.UnitTests/Mixins/ContentControlMixinTests.cs
  39. 9 9
      tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_InTemplate.cs
  40. 8 8
      tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Standalone.cs
  41. 2 2
      tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Unrooted.cs
  42. 1 1
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests.cs
  43. 1 1
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs
  44. 4 4
      tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs
  45. 3 3
      tests/Avalonia.Controls.UnitTests/Primitives/PopupRootTests.cs
  46. 4 4
      tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs
  47. 3 3
      tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs
  48. 5 5
      tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs
  49. 2 2
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
  50. 2 2
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_AutoSelect.cs
  51. 5 5
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs
  52. 2 2
      tests/Avalonia.Controls.UnitTests/Primitives/TabStripTests.cs
  53. 29 29
      tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs
  54. 6 6
      tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs
  55. 9 9
      tests/Avalonia.Controls.UnitTests/TabControlTests.cs
  56. 2 2
      tests/Avalonia.Controls.UnitTests/TextBoxTests.cs
  57. 2 2
      tests/Avalonia.Controls.UnitTests/TextBoxTests_DataValidation.cs
  58. 2 2
      tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
  59. 9 9
      tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
  60. 3 3
      tests/Avalonia.Controls.UnitTests/UserControlTests.cs
  61. 2 2
      tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs
  62. 2 2
      tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs
  63. 8 2
      tests/Avalonia.Markup.UnitTests/Data/BindingTests_ElementName.cs
  64. 3 2
      tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests_Converters.cs
  65. 3 3
      tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs
  66. 2 2
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs
  67. 2 2
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs
  68. 2 2
      tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs
  69. 4 4
      tests/Avalonia.ReactiveUI.UnitTests/AutoDataTemplateBindingHookTest.cs
  70. 4 4
      tests/Avalonia.ReactiveUI.UnitTests/TransitioningContentControlTest.cs
  71. 74 8
      tests/Avalonia.Styling.UnitTests/ControlLocatorTests.cs
  72. 6 6
      tests/Avalonia.Styling.UnitTests/SelectorTests_Multiple.cs
  73. 0 13
      tests/Avalonia.Styling.UnitTests/SetterTests.cs
  74. 0 15
      tests/Avalonia.Styling.UnitTests/StyledElementTests.cs
  75. 0 69
      tests/Avalonia.Styling.UnitTests/StyledElementTests_NameScope.cs
  76. 2 2
      tests/Avalonia.Styling.UnitTests/StyledElementTests_Resources.cs
  77. 19 29
      tests/Avalonia.UnitTests/TestRoot.cs
  78. 3 30
      tests/Avalonia.UnitTests/TestTemplatedRoot.cs

+ 1 - 1
src/Avalonia.Controls/AutoCompleteBox.cs

@@ -795,7 +795,7 @@ namespace Avalonia.Controls
                 var template =
                     new FuncDataTemplate(
                         typeof(object),
-                        o =>
+                        (o, _) =>
                         {
                             var control = new ContentControl();
                             control.Bind(ContentControl.ContentProperty, value);

+ 1 - 20
src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs

@@ -8,7 +8,7 @@ using JetBrains.Annotations;
 
 namespace Avalonia.Controls.Embedding
 {
-    public class EmbeddableControlRoot : TopLevel, IStyleable, IFocusScope, INameScope, IDisposable
+    public class EmbeddableControlRoot : TopLevel, IStyleable, IFocusScope, IDisposable
     {
         public EmbeddableControlRoot(IEmbeddableWindowImpl impl) : base(impl)
         {
@@ -51,25 +51,6 @@ namespace Avalonia.Controls.Embedding
             return rv;
         }
 
-        private readonly NameScope _nameScope = new NameScope();
-        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 void Register(string name, object element) => _nameScope.Register(name, element);
-
-        public object Find(string name) => _nameScope.Find(name);
-
-        public void Unregister(string name) => _nameScope.Unregister(name);
-
         Type IStyleable.StyleKey => typeof(EmbeddableControlRoot);
         public void Dispose() => PlatformImpl?.Dispose();
     }

+ 0 - 19
src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs

@@ -30,25 +30,6 @@ namespace Avalonia.Controls.Embedding.Offscreen
                 init.EndInit();
             }
         }
-        
-        private readonly NameScope _nameScope = new NameScope();
-        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 void Register(string name, object element) => _nameScope.Register(name, element);
-
-        public object Find(string name) => _nameScope.Find(name);
-
-        public void Unregister(string name) => _nameScope.Unregister(name);
 
         Type IStyleable.StyleKey => typeof(EmbeddableControlRoot);
         public void Dispose()

+ 11 - 3
src/Avalonia.Controls/Generators/TreeItemContainerGenerator.cs

@@ -92,7 +92,6 @@ namespace Avalonia.Controls.Generators
                     result.DataContext = item;
                 }
 
-                NameScope.SetNameScope((Control)(object)result, new NameScope());
                 Index.Add(item, result);
 
                 return result;
@@ -123,11 +122,20 @@ namespace Avalonia.Controls.Generators
             return false;
         }
 
+        class WrapperTreeDataTemplate : ITreeDataTemplate
+        {
+            private readonly IDataTemplate _inner;
+            public WrapperTreeDataTemplate(IDataTemplate inner) => _inner = inner;
+            public IControl Build(object param) => _inner.Build(param);
+            public bool SupportsRecycling => _inner.SupportsRecycling;
+            public bool Match(object data) => _inner.Match(data);
+            public InstancedBinding ItemsSelector(object item) => null;
+        }
+
         private ITreeDataTemplate GetTreeDataTemplate(object item, IDataTemplate primary)
         {
             var template = Owner.FindDataTemplate(item, primary) ?? FuncDataTemplate.Default;
-            var treeTemplate = template as ITreeDataTemplate ??
-                new FuncTreeDataTemplate(typeof(object), template.Build, x => null);
+            var treeTemplate = template as ITreeDataTemplate ?? new WrapperTreeDataTemplate(template);
             return treeTemplate;
         }
     }

+ 0 - 6
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@@ -325,12 +325,6 @@ namespace Avalonia.Controls.Presenters
                 {
                     _dataTemplate = dataTemplate;
                     newChild = _dataTemplate.Build(content);
-
-                    // Give the new control its own name scope.
-                    if (newChild is Control controlResult)
-                    {
-                        NameScope.SetNameScope(controlResult, new NameScope());
-                    }
                 }
             }
             else

+ 6 - 24
src/Avalonia.Controls/Primitives/TemplatedControl.cs

@@ -258,13 +258,16 @@ namespace Avalonia.Controls.Primitives
                     Logger.Verbose(LogArea.Control, this, "Creating control template");
 
                     var child = template.Build(this);
-                    var nameScope = new NameScope();
-                    NameScope.SetNameScope((Control)child, nameScope);
                     ApplyTemplatedParent(child);
-                    RegisterNames(child, nameScope);
                     ((ISetLogicalParent)child).SetParent(this);
                     VisualChildren.Add(child);
 
+                    var nameScope = (child is StyledElement styledChild) ? NameScope.GetNameScope(styledChild) : null;
+                    
+                    // Existing code kinda expect to see a NameScope even if it's empty
+                    if (nameScope == null)
+                        nameScope = new NameScope();
+
                     OnTemplateApplied(new TemplateAppliedEventArgs(nameScope));
                 }
 
@@ -342,26 +345,5 @@ namespace Avalonia.Controls.Primitives
                 }
             }
         }
-
-        /// <summary>
-        /// Registers each control with its name scope.
-        /// </summary>
-        /// <param name="control">The control.</param>
-        /// <param name="nameScope">The name scope.</param>
-        private void RegisterNames(IControl control, INameScope nameScope)
-        {
-            if (control.Name != null)
-            {
-                nameScope.Register(control.Name, control);
-            }
-
-            if (control.TemplatedParent == this)
-            {
-                foreach (IControl child in control.GetLogicalChildren())
-                {
-                    RegisterNames(child, nameScope);
-                }
-            }
-        }
     }
 }

+ 2 - 2
src/Avalonia.Controls/Templates/FuncControlTemplate.cs

@@ -16,9 +16,9 @@ namespace Avalonia.Controls.Templates
         /// Initializes a new instance of the <see cref="FuncControlTemplate"/> class.
         /// </summary>
         /// <param name="build">The build function.</param>
-        public FuncControlTemplate(Func<ITemplatedControl, IControl> build)
+        public FuncControlTemplate(Func<ITemplatedControl, INameScope, IControl> build)
             : base(build)
         {
         }
     }
-}
+}

+ 3 - 3
src/Avalonia.Controls/Templates/FuncControlTemplate`2.cs

@@ -17,9 +17,9 @@ namespace Avalonia.Controls.Templates
         /// Initializes a new instance of the <see cref="FuncControlTemplate{T}"/> class.
         /// </summary>
         /// <param name="build">The build function.</param>
-        public FuncControlTemplate(Func<T, IControl> build)
-            : base(x => build((T)x))
+        public FuncControlTemplate(Func<T, INameScope, IControl> build)
+            : base((x, s) => build((T)x, s))
         {
         }
     }
-}
+}

+ 4 - 4
src/Avalonia.Controls/Templates/FuncDataTemplate.cs

@@ -17,7 +17,7 @@ namespace Avalonia.Controls.Templates
         /// </summary>
         public static readonly FuncDataTemplate Default =
             new FuncDataTemplate<object>(
-                data =>
+                (data, s) =>
                 {
                     if (data != null)
                     {
@@ -49,7 +49,7 @@ namespace Avalonia.Controls.Templates
         /// <param name="supportsRecycling">Whether the control can be recycled.</param>
         public FuncDataTemplate(
             Type type, 
-            Func<object, IControl> build,
+            Func<object, INameScope, IControl> build,
             bool supportsRecycling = false)
             : this(o => IsInstance(o, type), build, supportsRecycling)
         {
@@ -67,7 +67,7 @@ namespace Avalonia.Controls.Templates
         /// <param name="supportsRecycling">Whether the control can be recycled.</param>
         public FuncDataTemplate(
             Func<object, bool> match,
-            Func<object, IControl> build,
+            Func<object, INameScope, IControl> build,
             bool supportsRecycling = false)
             : base(build)
         {
@@ -105,4 +105,4 @@ namespace Avalonia.Controls.Templates
             return (o != null) && t.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo());
         }
     }
-}
+}

+ 22 - 4
src/Avalonia.Controls/Templates/FuncDataTemplate`1.cs

@@ -18,7 +18,7 @@ namespace Avalonia.Controls.Templates
         /// A function which when passed an object of <typeparamref name="T"/> returns a control.
         /// </param>
         /// <param name="supportsRecycling">Whether the control can be recycled.</param>
-        public FuncDataTemplate(Func<T, IControl> build, bool supportsRecycling = false)
+        public FuncDataTemplate(Func<T, INameScope, IControl> build, bool supportsRecycling = false)
             : base(typeof(T), CastBuild(build), supportsRecycling)
         {
         }
@@ -35,12 +35,30 @@ namespace Avalonia.Controls.Templates
         /// <param name="supportsRecycling">Whether the control can be recycled.</param>
         public FuncDataTemplate(
             Func<T, bool> match,
-            Func<T, IControl> build,
+            Func<T, INameScope, IControl> build,
             bool supportsRecycling = false)
             : base(CastMatch(match), CastBuild(build), supportsRecycling)
         {
         }
 
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FuncDataTemplate{T}"/> class.
+        /// </summary>
+        /// <param name="match">
+        /// A function which determines whether the data template matches the specified data.
+        /// </param>
+        /// <param name="build">
+        /// A function which when passed an object of <typeparamref name="T"/> returns a control.
+        /// </param>
+        /// <param name="supportsRecycling">Whether the control can be recycled.</param>
+        public FuncDataTemplate(
+            Func<T, bool> match,
+            Func<T, IControl> build,
+            bool supportsRecycling = false)
+            : this(match, (a, _) => build(a), supportsRecycling)
+        {
+        }
+
         /// <summary>
         /// Casts a strongly typed match function to a weakly typed one.
         /// </summary>
@@ -57,9 +75,9 @@ namespace Avalonia.Controls.Templates
         /// <typeparam name="TResult">The strong data type.</typeparam>
         /// <param name="f">The strongly typed function.</param>
         /// <returns>The weakly typed function.</returns>
-        private static Func<object, TResult> CastBuild<TResult>(Func<T, TResult> f)
+        private static Func<object, INameScope, TResult> CastBuild<TResult>(Func<T, INameScope, TResult> f)
         {
-            return o => f((T)o);
+            return (o, s) => f((T)o, s);
         }
     }
 }

+ 24 - 0
src/Avalonia.Controls/Templates/FuncTemplateNameScopeExtensions.cs

@@ -0,0 +1,24 @@
+using System;
+
+namespace Avalonia.Controls.Templates
+{
+    public static class FuncTemplateNameScopeExtensions
+    {
+        public static T RegisterInNameScope<T>(this T control, INameScope scope)
+        where T : StyledElement
+        {
+            scope.Register(control.Name, control);
+            return control;
+        }
+
+        public static T WithNameScope<T>(this T control, INameScope scope)
+            where T : StyledElement
+        {
+            var existingScope = NameScope.GetNameScope(control);
+            if (existingScope != null && existingScope != scope)
+                throw new InvalidOperationException("Control already has a name scope");
+            NameScope.SetNameScope(control, scope);
+            return control;
+        }
+    }
+}

+ 9 - 4
src/Avalonia.Controls/Templates/FuncTemplate`2.cs

@@ -13,13 +13,13 @@ namespace Avalonia.Controls.Templates
     public class FuncTemplate<TParam, TControl> : ITemplate<TParam, TControl>
         where TControl : IControl
     {
-        private readonly Func<TParam, TControl> _func;
+        private readonly Func<TParam, INameScope, TControl> _func;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="FuncTemplate{TControl, TParam}"/> class.
         /// </summary>
         /// <param name="func">The function used to create the control.</param>
-        public FuncTemplate(Func<TParam, TControl> func)
+        public FuncTemplate(Func<TParam, INameScope, TControl> func)
         {
             Contract.Requires<ArgumentNullException>(func != null);
 
@@ -35,7 +35,12 @@ namespace Avalonia.Controls.Templates
         /// </returns>
         public TControl Build(TParam param)
         {
-            return _func(param);
+            var scope = new NameScope();
+            var rv = _func(param, scope);
+            // TODO: May be return the name scope alongside with the control instead?
+            if (rv is StyledElement sl)
+                NameScope.SetNameScope(sl, scope);
+            return rv;
         }
     }
-}
+}

+ 2 - 2
src/Avalonia.Controls/Templates/FuncTreeDataTemplate.cs

@@ -28,7 +28,7 @@ namespace Avalonia.Controls.Templates
         /// </param>
         public FuncTreeDataTemplate(
             Type type,
-            Func<object, IControl> build,
+            Func<object, INameScope, IControl> build,
             Func<object, IEnumerable> itemsSelector)
             : this(o => IsInstance(o, type), build, itemsSelector)
         {
@@ -48,7 +48,7 @@ namespace Avalonia.Controls.Templates
         /// </param>
         public FuncTreeDataTemplate(
             Func<object, bool> match,
-            Func<object, IControl> build,
+            Func<object, INameScope, IControl> build,
             Func<object, IEnumerable> itemsSelector)
             : base(match, build)
         {

+ 13 - 2
src/Avalonia.Controls/Templates/FuncTreeDataTemplate`1.cs

@@ -23,7 +23,7 @@ namespace Avalonia.Controls.Templates
         /// items.
         /// </param>
         public FuncTreeDataTemplate(
-            Func<T, Control> build,
+            Func<T, INameScope, Control> build,
             Func<T, IEnumerable> itemsSelector)
             : base(
                 typeof(T),
@@ -46,7 +46,7 @@ namespace Avalonia.Controls.Templates
         /// </param>
         public FuncTreeDataTemplate(
             Func<T, bool> match,
-            Func<T, Control> build,
+            Func<T, INameScope, Control> build,
             Func<T, IEnumerable> itemsSelector)
             : base(
                 CastMatch(match),
@@ -65,6 +65,17 @@ namespace Avalonia.Controls.Templates
             return o => (o is T) && f((T)o);
         }
 
+        /// <summary>
+        /// Casts a function with a typed parameter to an untyped function.
+        /// </summary>
+        /// <typeparam name="TResult">The result.</typeparam>
+        /// <param name="f">The typed function.</param>
+        /// <returns>The untyped function.</returns>
+        private static Func<object, INameScope, TResult> Cast<TResult>(Func<T, INameScope, TResult> f)
+        {
+            return (o, s) => f((T)o, s);
+        }
+        
         /// <summary>
         /// Casts a function with a typed parameter to an untyped function.
         /// </summary>

+ 1 - 33
src/Avalonia.Controls/UserControl.cs

@@ -9,40 +9,8 @@ namespace Avalonia.Controls
     /// <summary>
     /// Provides the base class for defining a new control that encapsulates related existing controls and provides its own logic.
     /// </summary>
-    public class UserControl : ContentControl, IStyleable, INameScope
+    public class UserControl : ContentControl, IStyleable
     {
-        private readonly NameScope _nameScope = new NameScope();
 
-        /// <inheritdoc/>
-        event EventHandler<NameScopeEventArgs> INameScope.Registered
-        {
-            add { _nameScope.Registered += value; }
-            remove { _nameScope.Registered -= value; }
-        }
-
-        /// <inheritdoc/>
-        event EventHandler<NameScopeEventArgs> INameScope.Unregistered
-        {
-            add { _nameScope.Unregistered += value; }
-            remove { _nameScope.Unregistered -= value; }
-        }
-
-        /// <inheritdoc/>
-        void INameScope.Register(string name, object element)
-        {
-            _nameScope.Register(name, element);
-        }
-
-        /// <inheritdoc/>
-        object INameScope.Find(string name)
-        {
-            return _nameScope.Find(name);
-        }
-
-        /// <inheritdoc/>
-        void INameScope.Unregister(string name)
-        {
-            _nameScope.Unregister(name);
-        }
     }
 }

+ 1 - 33
src/Avalonia.Controls/Window.cs

@@ -48,7 +48,7 @@ namespace Avalonia.Controls
     /// <summary>
     /// A top-level window.
     /// </summary>
-    public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot, INameScope
+    public class Window : WindowBase, IStyleable, IFocusScope, ILayoutRoot
     {
         /// <summary>
         /// Defines the <see cref="SizeToContent"/> property.
@@ -157,20 +157,6 @@ namespace Avalonia.Controls
             _maxPlatformClientSize = PlatformImpl?.MaxClientSize ?? default(Size);
         }
 
-        /// <inheritdoc/>
-        event EventHandler<NameScopeEventArgs> INameScope.Registered
-        {
-            add { _nameScope.Registered += value; }
-            remove { _nameScope.Registered -= value; }
-        }
-
-        /// <inheritdoc/>
-        event EventHandler<NameScopeEventArgs> INameScope.Unregistered
-        {
-            add { _nameScope.Unregistered += value; }
-            remove { _nameScope.Unregistered -= value; }
-        }
-
         /// <summary>
         /// Gets the platform-specific window implementation.
         /// </summary>
@@ -494,24 +480,6 @@ namespace Avalonia.Controls
             }
         }
 
-        /// <inheritdoc/>
-        void INameScope.Register(string name, object element)
-        {
-            _nameScope.Register(name, element);
-        }
-
-        /// <inheritdoc/>
-        object INameScope.Find(string name)
-        {
-            return _nameScope.Find(name);
-        }
-
-        /// <inheritdoc/>
-        void INameScope.Unregister(string name)
-        {
-            _nameScope.Unregister(name);
-        }
-
         /// <inheritdoc/>
         protected override Size MeasureOverride(Size availableSize)
         {

+ 2 - 2
src/Avalonia.ReactiveUI/AutoDataTemplateBindingHook.cs

@@ -16,7 +16,7 @@ namespace Avalonia.ReactiveUI
     /// </summary>
     public class AutoDataTemplateBindingHook : IPropertyBindingHook
     {
-        private static FuncDataTemplate DefaultItemTemplate = new FuncDataTemplate<object>(x =>
+        private static FuncDataTemplate DefaultItemTemplate = new FuncDataTemplate<object>((x, _) =>
         {
             var control = new ViewModelViewHost();
             var context = control.GetObservable(Control.DataContextProperty);
@@ -52,4 +52,4 @@ namespace Avalonia.ReactiveUI
             return true;
         }
     }
-}
+}

+ 15 - 0
src/Avalonia.Styling/Controls/NameScope.cs

@@ -106,6 +106,21 @@ namespace Avalonia.Controls
             }
         }
 
+        /// <summary>
+        /// Registers an element in the name scope associated with the scopeElement.
+        /// Creates the scope if one isn't associated with the element yet
+        /// </summary>
+        /// <param name="scopeElement"></param>
+        /// <param name="name"></param>
+        /// <param name="element"></param>
+        public static void Register(StyledElement scopeElement, string name, object element)
+        {
+            var scope = scopeElement as INameScope ?? GetNameScope(scopeElement);
+            if(scope == null)
+                SetNameScope(scopeElement, scope = new NameScope());
+            scope.Register(name, element);
+        }
+        
         /// <summary>
         /// Finds a named element in the name scope.
         /// </summary>

+ 41 - 0
src/Avalonia.Styling/Controls/NameScopeExtensions.cs

@@ -37,6 +37,25 @@ namespace Avalonia.Controls
             return (T)result;
         }
 
+        /// <summary>
+        /// Finds a named element in an <see cref="INameScope"/>.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="anchor">The control to take the name scope from.</param>
+        /// <param name="name">The name.</param>
+        /// <returns>The named element or null if not found.</returns>
+        public static T Find<T>(this ILogical anchor, string name)
+            where T : class
+        {
+            Contract.Requires<ArgumentNullException>(anchor != null);
+            Contract.Requires<ArgumentNullException>(name != null);
+            var styledAnchor = anchor as StyledElement;
+            if (styledAnchor == null)
+                return null;
+            var nameScope = (anchor as INameScope) ?? NameScope.GetNameScope(styledAnchor);
+            return nameScope?.Find<T>(name);
+        }
+
         /// <summary>
         /// Gets a named element from an <see cref="INameScope"/> or throws if no element of the
         /// requested name was found.
@@ -67,6 +86,28 @@ namespace Avalonia.Controls
             return (T)result;
         }
 
+        /// <summary>
+        /// Gets a named element from an <see cref="INameScope"/> or throws if no element of the
+        /// requested name was found.
+        /// </summary>
+        /// <typeparam name="T">The element type.</typeparam>
+        /// <param name="anchor">The control to take the name scope from.</param>
+        /// <param name="name">The name.</param>
+        /// <returns>The named element.</returns>
+        public static T Get<T>(this ILogical anchor, string name)
+            where T : class
+        {
+            Contract.Requires<ArgumentNullException>(anchor != null);
+            Contract.Requires<ArgumentNullException>(name != null);
+               
+            var nameScope = (anchor as INameScope) ?? NameScope.GetNameScope((StyledElement)anchor);
+            if (nameScope == null)
+                throw new InvalidOperationException(
+                    "The control doesn't have an associated name scope, probably no registrations has been done yet");
+            
+            return nameScope.Get<T>(name);
+        }
+        
         public static INameScope FindNameScope(this ILogical control)
         {
             Contract.Requires<ArgumentNullException>(control != null);

+ 0 - 21
src/Avalonia.Styling/StyledElement.cs

@@ -61,7 +61,6 @@ namespace Avalonia
         private readonly Classes _classes = new Classes();
         private bool _isAttachedToLogicalTree;
         private IAvaloniaList<ILogical> _logicalChildren;
-        private INameScope _nameScope;
         private IResourceDictionary _resources;
         private Styles _styles;
         private bool _styled;
@@ -82,7 +81,6 @@ namespace Avalonia
         /// </summary>
         public StyledElement()
         {
-            _nameScope = this as INameScope;
             _isAttachedToLogicalTree = this is IStyleRoot;
         }
 
@@ -381,7 +379,6 @@ namespace Avalonia
         {
             if (_initCount == 0 && (!_styled || force))
             {
-                RegisterWithNameScope();
                 ApplyStyling();
                 _styled = true;
             }
@@ -675,19 +672,6 @@ namespace Avalonia
             AvaloniaLocator.Current.GetService<IStyler>()?.ApplyStyles(this);
         }
 
-        private void RegisterWithNameScope()
-        {
-            if (_nameScope == null)
-            {
-                _nameScope = NameScope.GetNameScope(this) ?? ((StyledElement)Parent)?._nameScope;
-            }
-
-            if (Name != null)
-            {
-                _nameScope?.Register(Name, this);
-            }
-        }
-
         private static void ValidateLogicalChild(ILogical c)
         {
             if (c == null)
@@ -724,11 +708,6 @@ namespace Avalonia
         {
             if (_isAttachedToLogicalTree)
             {
-                if (Name != null)
-                {
-                    _nameScope?.Unregister(Name);
-                }
-
                 _isAttachedToLogicalTree = false;
                 _styleDetach.OnNext(this);
                 OnDetachedFromLogicalTree(e);

+ 0 - 1
src/Avalonia.Styling/Styling/Setter.cs

@@ -99,7 +99,6 @@ namespace Avalonia.Styling
                 if (template != null && !isPropertyOfTypeITemplate)
                 {
                     var materialized = template.Build();
-                    NameScope.SetNameScope((StyledElement)materialized, new NameScope());
                     value = materialized;
                 }
 

+ 1 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/AvaloniaXamlIlLanguage.cs

@@ -35,6 +35,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions
                 },
                 ProvideValueTarget = typeSystem.GetType("Avalonia.Markup.Xaml.IProvideValueTarget"),
                 RootObjectProvider = typeSystem.GetType("Avalonia.Markup.Xaml.IRootObjectProvider"),
+                RootObjectProviderIntermediateRootPropertyName = "IntermediateRootObject",
                 UriContextProvider = typeSystem.GetType("Avalonia.Markup.Xaml.IUriContext"),
                 ParentStackProvider =
                     typeSystem.GetType("Avalonia.Markup.Xaml.XamlIl.Runtime.IAvaloniaXamlIlParentStackProvider"),

+ 32 - 37
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AddNameScopeRegistration.cs

@@ -15,7 +15,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
                 && pa.Property.DeclaringType.FullName == "Avalonia.StyledElement")
             {
                 if (context.ParentNodes().FirstOrDefault() is XamlIlManipulationGroupNode mg
-                    && mg.Children.OfType<ScopeRegistrationNode>().Any())
+                    && mg.Children.OfType<AvaloniaNameScopeRegistrationXamlIlNode>().Any())
                     return node;
                 
                 IXamlIlAstValueNode value = null;
@@ -41,7 +41,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
                         Children =
                         {
                             pa,
-                            new ScopeRegistrationNode(value)
+                            new AvaloniaNameScopeRegistrationXamlIlNode(value, context.GetAvaloniaTypes())
                         }
                     };
             }
@@ -49,46 +49,41 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
             return node;
         }
 
-        class ScopeRegistrationNode : XamlIlAstNode, IXamlIlAstManipulationNode, IXamlIlAstEmitableNode
+        
+    }
+
+    class AvaloniaNameScopeRegistrationXamlIlNode : XamlIlAstNode, IXamlIlAstManipulationNode, IXamlIlAstEmitableNode
+    {
+        private readonly AvaloniaXamlIlWellKnownTypes _types;
+        public IXamlIlAstValueNode Name { get; set; }
+
+        public AvaloniaNameScopeRegistrationXamlIlNode(IXamlIlAstValueNode name, AvaloniaXamlIlWellKnownTypes types) : base(name)
         {
-            public IXamlIlAstValueNode Value { get; set; }
-            public ScopeRegistrationNode(IXamlIlAstValueNode value) : base(value)
-            {
-                Value = value;
-            }
+            _types = types;
+            Name = name;
+        }
 
-            public override void VisitChildren(IXamlIlAstVisitor visitor)
-                => Value = (IXamlIlAstValueNode)Value.Visit(visitor);
+        public override void VisitChildren(IXamlIlAstVisitor visitor)
+            => Name = (IXamlIlAstValueNode)Name.Visit(visitor);
 
-            public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
+        public XamlIlNodeEmitResult Emit(XamlIlEmitContext context, IXamlIlEmitter codeGen)
+        {
+            using (var targetLoc = context.GetLocal(context.Configuration.WellKnownTypes.Object))
             {
-                var exts = context.Configuration.TypeSystem.GetType("Avalonia.Controls.NameScopeExtensions");
-                var findNameScope = exts.FindMethod(m => m.Name == "FindNameScope");
-                var registerMethod = findNameScope.ReturnType.FindMethod(m => m.Name == "Register");
-                using (var targetLoc = context.GetLocal(context.Configuration.WellKnownTypes.Object))
-                using (var nameScopeLoc = context.GetLocal(findNameScope.ReturnType))
-                {
-                    var exit = codeGen.DefineLabel();
-                    codeGen
-                        // var target = {pop}    
-                        .Stloc(targetLoc.Local)
-                        // var scope = target.FindNameScope()
-                        .Ldloc(targetLoc.Local)
-                        .Castclass(findNameScope.Parameters[0])
-                        .EmitCall(findNameScope)
-                        .Stloc(nameScopeLoc.Local)
-                        // if({scope} != null) goto call;
-                        .Ldloc(nameScopeLoc.Local)
-                        .Brfalse(exit)
-                        .Ldloc(nameScopeLoc.Local);
-                    context.Emit(Value, codeGen, Value.Type.GetClrType());
-                    codeGen
-                        .Ldloc(targetLoc.Local)
-                        .EmitCall(registerMethod)
-                        .MarkLabel(exit);
-                }
-                return XamlIlNodeEmitResult.Void(1);
+                codeGen
+                    // var target = {pop}    
+                    .Stloc(targetLoc.Local)
+                    // NameScope.Register(context.IntermediateRoot, Name, target)
+                    .Ldloc(context.ContextLocal)
+                    .Ldfld(context.RuntimeContext.IntermediateRootObjectField)
+                    .Castclass(_types.StyledElement);
+                context.Emit(Name, codeGen, Name.Type.GetClrType());
+                codeGen
+                    .Ldloc(targetLoc.Local)
+                    .EmitCall(_types.NameScopeStaticRegister, true);
             }
+
+            return XamlIlNodeEmitResult.Void(1);
         }
     }
 }

+ 12 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs

@@ -19,6 +19,9 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
         public IXamlIlType Transitions { get; }
         public IXamlIlType AssignBindingAttribute { get; }
         public IXamlIlType UnsetValueType { get; }
+        public IXamlIlType StyledElement { get; }
+        public IXamlIlType NameScope { get; }
+        public IXamlIlMethod NameScopeStaticRegister { get; }
         
         public AvaloniaXamlIlWellKnownTypes(XamlIlAstTransformationContext ctx)
         {
@@ -37,6 +40,15 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers
                 AvaloniaProperty,
                 IBinding, ctx.Configuration.WellKnownTypes.Object);
             UnsetValueType = ctx.Configuration.TypeSystem.GetType("Avalonia.UnsetValueType");
+            StyledElement = ctx.Configuration.TypeSystem.GetType("Avalonia.StyledElement");
+            NameScope = ctx.Configuration.TypeSystem.GetType("Avalonia.Controls.NameScope");
+            NameScopeStaticRegister = NameScope.FindMethod(
+                new FindMethodMethodSignature("Register", XamlIlTypes.Void,
+                     StyledElement, XamlIlTypes.String, XamlIlTypes.Object)
+                {
+                    IsStatic = true, DeclaringOnly = true, IsExactMatch = true
+                });
+
             AvaloniaObjectSetValueMethod = AvaloniaObject.FindMethod("SetValue", XamlIlTypes.Void,
                 false, AvaloniaProperty, XamlIlTypes.Object, BindingPriority);
         }

+ 1 - 0
src/Markup/Avalonia.Markup.Xaml/XamlIl/Runtime/XamlIlRuntimeHelpers.cs

@@ -56,6 +56,7 @@ namespace Avalonia.Markup.Xaml.XamlIl.Runtime
             }
 
             public object RootObject { get; }
+            public object IntermediateRootObject => RootObject;
         }
 
 

+ 1 - 1
src/Markup/Avalonia.Markup.Xaml/XamlIl/xamlil.github

@@ -1 +1 @@
-Subproject commit 894b2c02827fd5eb16a338de5d5b6c9fbc60fef5
+Subproject commit fc52295ea6c45f709bf63975026a4a18ce230be9

+ 8 - 0
src/Markup/Avalonia.Markup.Xaml/XamlTypes.cs

@@ -10,7 +10,15 @@ namespace Avalonia.Markup.Xaml
     
     public interface IRootObjectProvider
     {
+        /// <summary>
+        /// The root object of the xaml file
+        /// </summary>
         object RootObject { get; }
+        /// <summary>
+        /// The "current" root object, contains either the root of the xaml file
+        /// or the root object of the control/data template 
+        /// </summary>
+        object IntermediateRootObject { get; }
     }
     
     public interface IUriContext

+ 5 - 5
tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs

@@ -1012,25 +1012,25 @@ namespace Avalonia.Controls.UnitTests
         }
         private IControlTemplate CreateTemplate()
         {
-            return new FuncControlTemplate<AutoCompleteBox>(control =>
+            return new FuncControlTemplate<AutoCompleteBox>((control, scope) =>
             {
                 var textBox =
                     new TextBox
                     {
                         Name = "PART_TextBox"
-                    };
+                    }.RegisterInNameScope(scope);
                 var listbox =
                     new ListBox
                     {
                         Name = "PART_SelectingItemsControl"
-                    };
+                    }.RegisterInNameScope(scope);
                 var popup =
                     new Popup
                     {
                         Name = "PART_Popup"
-                    };
+                    }.RegisterInNameScope(scope);
 
-                var panel = new Panel();
+                var panel = new Panel().WithNameScope(scope);
                 panel.Children.Add(textBox);
                 panel.Children.Add(popup);
                 panel.Children.Add(listbox);

+ 2 - 2
tests/Avalonia.Controls.UnitTests/CarouselTests.cs

@@ -302,7 +302,7 @@ namespace Avalonia.Controls.UnitTests
             Assert.Equal("FooBar", target.SelectedItem);
         }
 
-        private Control CreateTemplate(Carousel control)
+        private Control CreateTemplate(Carousel control, INameScope scope)
         {
             return new CarouselPresenter
             {
@@ -312,7 +312,7 @@ namespace Avalonia.Controls.UnitTests
                 [~CarouselPresenter.ItemsPanelProperty] = control[~Carousel.ItemsPanelProperty],
                 [~CarouselPresenter.SelectedIndexProperty] = control[~Carousel.SelectedIndexProperty],
                 [~CarouselPresenter.PageTransitionProperty] = control[~Carousel.PageTransitionProperty],
-            };
+            }.RegisterInNameScope(scope).WithNameScope(scope);
         }
     }
 }

+ 5 - 5
tests/Avalonia.Controls.UnitTests/ComboBoxTests.cs

@@ -80,7 +80,7 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate GetTemplate()
         {
-            return new FuncControlTemplate<ComboBox>(parent =>
+            return new FuncControlTemplate<ComboBox>((parent, scope) =>
             {
                 return new Panel
                 {
@@ -94,7 +94,7 @@ namespace Avalonia.Controls.UnitTests
                         new ToggleButton
                         {
                             Name = "toggle",
-                        },
+                        }.RegisterInNameScope(scope),
                         new Popup
                         {
                             Name = "PART_Popup",
@@ -102,10 +102,10 @@ namespace Avalonia.Controls.UnitTests
                             {
                                 Name = "PART_ItemsPresenter",
                                 [!ItemsPresenter.ItemsProperty] = parent[!ComboBox.ItemsProperty],
-                            }
-                        }
+                            }.RegisterInNameScope(scope)
+                        }.RegisterInNameScope(scope)
                     }
-                };
+                }.WithNameScope(scope);
             });
         }
     }

+ 6 - 6
tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

@@ -126,7 +126,7 @@ namespace Avalonia.Controls.UnitTests
             var target = new ContentControl
             {
                 Template = GetTemplate(),
-                ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas()),
+                ContentTemplate = new FuncDataTemplate<string>((_, __) => new Canvas()),
             };
 
             target.Content = "Foo";
@@ -302,8 +302,8 @@ namespace Avalonia.Controls.UnitTests
 
             var target = new ContentControl
             {
-                Template = new FuncControlTemplate<ContentControl>(_ => presenter),
-                ContentTemplate = new FuncDataTemplate<string>(x => new Canvas()),
+                Template = new FuncControlTemplate<ContentControl>((_, __) => presenter),
+                ContentTemplate = new FuncDataTemplate<string>((_, __) => new Canvas()),
                 Content = "foo",
             };
                         
@@ -333,7 +333,7 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate GetTemplate()
         {
-            return new FuncControlTemplate<ContentControl>(parent =>
+            return new FuncControlTemplate<ContentControl>((parent, scope) =>
             {
                 return new Border
                 {
@@ -343,8 +343,8 @@ namespace Avalonia.Controls.UnitTests
                         Name = "PART_ContentPresenter",
                         [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
                         [~ContentPresenter.ContentTemplateProperty] = parent[~ContentControl.ContentTemplateProperty],
-                    }
-                };
+                    }.RegisterInNameScope(scope)
+                }.WithNameScope(scope);
             });
         }
     }

+ 6 - 6
tests/Avalonia.Controls.UnitTests/DatePickerTests.cs

@@ -93,30 +93,30 @@ namespace Avalonia.Controls.UnitTests
 
         private IControlTemplate CreateTemplate()
         {
-            return new FuncControlTemplate<DatePicker>(control =>
+            return new FuncControlTemplate<DatePicker>((control, scope) =>
             {
                 var textBox = 
                     new TextBox
                     {
                         Name = "PART_TextBox"
-                    };
+                    }.RegisterInNameScope(scope);
                 var button =
                     new Button
                     {
                         Name = "PART_Button"
-                    };
+                    }.RegisterInNameScope(scope);
                 var calendar =
                     new Calendar
                     {
                         Name = "PART_Calendar"
-                    };
+                    }.RegisterInNameScope(scope);
                 var popup =
                     new Popup
                     {
                         Name = "PART_Popup"
-                    };
+                    }.RegisterInNameScope(scope);
 
-                var panel = new Panel();
+                var panel = new Panel().WithNameScope(scope);
                 panel.Children.Add(textBox);
                 panel.Children.Add(button);
                 panel.Children.Add(popup);

+ 12 - 9
tests/Avalonia.Controls.UnitTests/GridSplitterTests.cs

@@ -20,6 +20,7 @@ namespace Avalonia.Controls.UnitTests
         [Fact]
         public void Detects_Horizontal_Orientation()
         {
+            GridSplitter splitter;
             var grid = new Grid()
                        {
                             RowDefinitions = new RowDefinitions("*,Auto,*"),
@@ -27,7 +28,7 @@ namespace Avalonia.Controls.UnitTests
                             Children =
                             {
                                 new Border { [Grid.RowProperty] = 0 },
-                                new GridSplitter { [Grid.RowProperty] = 1, Name = "splitter" },
+                                (splitter = new GridSplitter { [Grid.RowProperty] = 1 }),
                                 new Border { [Grid.RowProperty] = 2 }
                             }
                        };
@@ -35,12 +36,13 @@ namespace Avalonia.Controls.UnitTests
             var root = new TestRoot { Child = grid };
             root.Measure(new Size(100, 300));
             root.Arrange(new Rect(0, 0, 100, 300));
-            Assert.Contains(grid.FindControl<GridSplitter>("splitter").Classes, ":horizontal".Equals);
+            Assert.Contains(splitter.Classes, ":horizontal".Equals);
         }
 
         [Fact]
         public void Detects_Vertical_Orientation()
         {
+            GridSplitter splitter;
             var grid = new Grid()
                        {
                             ColumnDefinitions = new ColumnDefinitions("*,Auto,*"),
@@ -48,7 +50,7 @@ namespace Avalonia.Controls.UnitTests
                             Children =
                             {
                                 new Border { [Grid.ColumnProperty] = 0 },
-                                new GridSplitter { [Grid.ColumnProperty] = 1, Name = "splitter" },
+                                (splitter = new GridSplitter { [Grid.ColumnProperty] = 1}),
                                 new Border { [Grid.ColumnProperty] = 2 },
                             }
                        };
@@ -56,12 +58,13 @@ namespace Avalonia.Controls.UnitTests
             var root = new TestRoot { Child = grid };
             root.Measure(new Size(100, 300));
             root.Arrange(new Rect(0, 0, 100, 300));
-            Assert.Contains(grid.FindControl<GridSplitter>("splitter").Classes, ":vertical".Equals);
+            Assert.Contains(splitter.Classes, ":vertical".Equals);
         }
 
         [Fact]
         public void Detects_With_Both_Auto()
         {
+            GridSplitter splitter;
             var grid = new Grid()
                        {
                             ColumnDefinitions = new ColumnDefinitions("Auto,Auto,Auto"),
@@ -69,7 +72,7 @@ namespace Avalonia.Controls.UnitTests
                             Children =
                             {
                                 new Border { [Grid.ColumnProperty] = 0 },
-                                new GridSplitter { [Grid.ColumnProperty] = 1, Name = "splitter" },
+                                (splitter = new GridSplitter { [Grid.ColumnProperty] = 1}),
                                 new Border { [Grid.ColumnProperty] = 2 },
                             }
                        };
@@ -77,7 +80,7 @@ namespace Avalonia.Controls.UnitTests
             var root = new TestRoot { Child = grid };
             root.Measure(new Size(100, 300));
             root.Arrange(new Rect(0, 0, 100, 300));
-            Assert.Contains(grid.FindControl<GridSplitter>("splitter").Classes, ":vertical".Equals);
+            Assert.Contains(splitter.Classes, ":vertical".Equals);
         }
 
         [Fact]
@@ -129,13 +132,14 @@ namespace Avalonia.Controls.UnitTests
         [Fact]
         public void In_First_Position_Doesnt_Throw_Exception()
         {
+            GridSplitter splitter;
             var grid = new Grid()
                        {
                             ColumnDefinitions = new ColumnDefinitions("Auto,*,*"),
                             RowDefinitions = new RowDefinitions("*,*"),
                             Children =
                             {
-                                new GridSplitter { [Grid.ColumnProperty] = 0, Name = "splitter" },
+                                (splitter = new GridSplitter { [Grid.ColumnProperty] = 0} ),
                                 new Border { [Grid.ColumnProperty] = 1 },
                                 new Border { [Grid.ColumnProperty] = 2 },
                             }
@@ -144,7 +148,6 @@ namespace Avalonia.Controls.UnitTests
             var root = new TestRoot { Child = grid };
             root.Measure(new Size(100, 300));
             root.Arrange(new Rect(0, 0, 100, 300));
-            var splitter = grid.FindControl<GridSplitter>("splitter");
             splitter.RaiseEvent(new VectorEventArgs
                                 {
                                     RoutedEvent = Thumb.DragDeltaEvent,
@@ -199,4 +202,4 @@ namespace Avalonia.Controls.UnitTests
             Assert.Equal(columnDefinitions[2].Width, new GridLength(80, GridUnitType.Star));
         }
     }
-}
+}

+ 3 - 3
tests/Avalonia.Controls.UnitTests/HeaderedItemsControlTests .cs

@@ -63,7 +63,7 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate GetTemplate()
         {
-            return new FuncControlTemplate<HeaderedItemsControl>(parent =>
+            return new FuncControlTemplate<HeaderedItemsControl>((parent, scope) =>
             {
                 return new Border
                 {
@@ -71,8 +71,8 @@ namespace Avalonia.Controls.UnitTests
                     {
                         Name = "PART_HeaderPresenter",
                         [~ContentPresenter.ContentProperty] = parent[~HeaderedItemsControl.HeaderProperty],
-                    }
-                };
+                    }.RegisterInNameScope(scope)
+                }.WithNameScope(scope);
             });
         }
     }

+ 5 - 5
tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs

@@ -23,7 +23,7 @@ namespace Avalonia.Controls.UnitTests
             var target = new ItemsControl
             {
                 Template = GetTemplate(),
-                ItemTemplate = new FuncDataTemplate<string>(_ => new Canvas()),
+                ItemTemplate = new FuncDataTemplate<string>((_, __) => new Canvas()),
             };
 
             target.Items = new[] { "Foo" };
@@ -411,7 +411,7 @@ namespace Avalonia.Controls.UnitTests
                 DataContext = "Base",
                 DataTemplates =
                 {
-                    new FuncDataTemplate<Item>(x => new Button { Content = x })
+                    new FuncDataTemplate<Item>((x, __) => new Button { Content = x })
                 },
                 Items = items,
             };
@@ -578,7 +578,7 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate GetTemplate()
         {
-            return new FuncControlTemplate<ItemsControl>(parent =>
+            return new FuncControlTemplate<ItemsControl>((parent, scope) =>
             {
                 return new Border
                 {
@@ -588,8 +588,8 @@ namespace Avalonia.Controls.UnitTests
                         Name = "PART_ItemsPresenter",
                         MemberSelector = parent.MemberSelector,
                         [~ItemsPresenter.ItemsProperty] = parent[~ItemsControl.ItemsProperty],
-                    }
-                };
+                    }.RegisterInNameScope(scope)
+                }.WithNameScope(scope);
             });
         }
 

+ 15 - 15
tests/Avalonia.Controls.UnitTests/ListBoxTests.cs

@@ -25,7 +25,7 @@ namespace Avalonia.Controls.UnitTests
             {
                 Template = ListBoxTemplate(),
                 Items = new[] { "Foo" },
-                ItemTemplate = new FuncDataTemplate<string>(_ => new Canvas()),
+                ItemTemplate = new FuncDataTemplate<string>((_, __) => new Canvas()),
             };
 
             Prepare(target);
@@ -113,7 +113,7 @@ namespace Avalonia.Controls.UnitTests
                     DataContext = "Base",
                     DataTemplates =
                     {
-                        new FuncDataTemplate<Item>(x => new Button { Content = x })
+                        new FuncDataTemplate<Item>((x, _) => new Button { Content = x })
                     },
                     Items = items,
                 };
@@ -138,7 +138,7 @@ namespace Avalonia.Controls.UnitTests
             {
                 Template = ListBoxTemplate(),
                 Items = Enumerable.Range(0, 20).Select(x => $"Item {x}").ToList(),
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Height = 10 }),
                 SelectedIndex = 0,
             };
 
@@ -162,7 +162,7 @@ namespace Avalonia.Controls.UnitTests
             {
                 Template = ListBoxTemplate(),
                 Items = Enumerable.Range(0, 20).Select(x => $"Item {x}").ToList(),
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Width = 20, Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
                 SelectedIndex = 0,
             };
 
@@ -181,7 +181,7 @@ namespace Avalonia.Controls.UnitTests
             {
                 Template = ListBoxTemplate(),
                 Items = items,
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Width = 20, Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
                 SelectedIndex = 0,
             };
 
@@ -205,7 +205,7 @@ namespace Avalonia.Controls.UnitTests
                 Template = ListBoxTemplate(),
                 Items = items,
                 SelectionMode = SelectionMode.Toggle,
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Height = 10 })
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Height = 10 })
             };
 
             Prepare(target);
@@ -239,7 +239,7 @@ namespace Avalonia.Controls.UnitTests
             {
                 Template = ListBoxTemplate(),
                 Items = items,
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Height = 11 })
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Height = 11 })
             };
 
             Prepare(target);
@@ -287,7 +287,7 @@ namespace Avalonia.Controls.UnitTests
                 target.DataContext = items;
                 target.VirtualizationMode = virtualizationMode;
 
-                target.ItemTemplate = new FuncDataTemplate<object>(c =>
+                target.ItemTemplate = new FuncDataTemplate<object>((c, _) =>
                 {
                     var tb = new TextBlock() { Height = 10, Width = 30 };
                     tb.Bind(TextBlock.TextProperty, new Data.Binding());
@@ -334,7 +334,7 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate ListBoxTemplate()
         {
-            return new FuncControlTemplate<ListBox>(parent =>
+            return new FuncControlTemplate<ListBox>((parent, scope) =>
                 new ScrollViewer
                 {
                     Name = "PART_ScrollViewer",
@@ -345,24 +345,24 @@ namespace Avalonia.Controls.UnitTests
                         [~ItemsPresenter.ItemsProperty] = parent.GetObservable(ItemsControl.ItemsProperty).ToBinding(),
                         [~ItemsPresenter.ItemsPanelProperty] = parent.GetObservable(ItemsControl.ItemsPanelProperty).ToBinding(),
                         [~ItemsPresenter.VirtualizationModeProperty] = parent.GetObservable(ListBox.VirtualizationModeProperty).ToBinding(),
-                    }
-                });
+                    }.RegisterInNameScope(scope)
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private FuncControlTemplate ListBoxItemTemplate()
         {
-            return new FuncControlTemplate<ListBoxItem>(parent =>
+            return new FuncControlTemplate<ListBoxItem>((parent, scope) =>
                 new ContentPresenter
                 {
                     Name = "PART_ContentPresenter",
                     [!ContentPresenter.ContentProperty] = parent[!ListBoxItem.ContentProperty],
                     [!ContentPresenter.ContentTemplateProperty] = parent[!ListBoxItem.ContentTemplateProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private FuncControlTemplate ScrollViewerTemplate()
         {
-            return new FuncControlTemplate<ScrollViewer>(parent =>
+            return new FuncControlTemplate<ScrollViewer>((parent, scope) =>
                 new ScrollContentPresenter
                 {
                     Name = "PART_ContentPresenter",
@@ -370,7 +370,7 @@ namespace Avalonia.Controls.UnitTests
                     [~~ScrollContentPresenter.ExtentProperty] = parent[~~ScrollViewer.ExtentProperty],
                     [~~ScrollContentPresenter.OffsetProperty] = parent[~~ScrollViewer.OffsetProperty],
                     [~~ScrollContentPresenter.ViewportProperty] = parent[~~ScrollViewer.ViewportProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private void Prepare(ListBox target)

+ 7 - 6
tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs

@@ -245,7 +245,7 @@ namespace Avalonia.Controls.UnitTests
             }
         }
 
-        private Control CreateListBoxTemplate(ITemplatedControl parent)
+        private Control CreateListBoxTemplate(ITemplatedControl parent, INameScope scope)
         {
             return new ScrollViewer
             {
@@ -254,17 +254,18 @@ namespace Avalonia.Controls.UnitTests
                 {
                     Name = "PART_ItemsPresenter",
                     [~ItemsPresenter.ItemsProperty] = parent.GetObservable(ItemsControl.ItemsProperty).ToBinding(),
-                }
-            };
+                }.RegisterInNameScope(scope)
+            }.WithNameScope(scope);
         }
 
-        private Control CreateScrollViewerTemplate(ITemplatedControl parent)
+        private Control CreateScrollViewerTemplate(ITemplatedControl parent, INameScope scope)
         {
             return new ScrollContentPresenter
             {
                 Name = "PART_ContentPresenter",
-                [~ContentPresenter.ContentProperty] = parent.GetObservable(ContentControl.ContentProperty).ToBinding(),
-            };
+                [~ContentPresenter.ContentProperty] =
+                    parent.GetObservable(ContentControl.ContentProperty).ToBinding(),
+            }.RegisterInNameScope(scope).WithNameScope(scope);
         }
 
         private void ApplyTemplate(ListBox target)

+ 9 - 8
tests/Avalonia.Controls.UnitTests/Mixins/ContentControlMixinTests.cs

@@ -21,15 +21,16 @@ namespace Avalonia.Controls.UnitTests.Mixins
         {
             var target = new TestControl()
             {
-                Template = new FuncControlTemplate(_ => new Panel
+                Template = new FuncControlTemplate((_, scope) => new Panel
                 {
                     Children =
                     {
-                        new ContentPresenter { Name = "Content_1_Presenter" },
-                        new ContentPresenter { Name = "Content_2_Presenter" }
+                        new ContentPresenter {Name = "Content_1_Presenter"}.RegisterInNameScope(scope),
+                        new ContentPresenter {Name = "Content_2_Presenter"}.RegisterInNameScope(scope)
                     }
-                })
+                }.WithNameScope(scope))
             };
+            
 
             var ex = Record.Exception(() => target.ApplyTemplate());
 
@@ -43,14 +44,14 @@ namespace Avalonia.Controls.UnitTests.Mixins
             var p2 = new ContentPresenter { Name = "Content_2_Presenter" };
             var target = new TestControl
             {
-                Template = new FuncControlTemplate(_ => new Panel
+                Template = new FuncControlTemplate((_, scope) => new Panel
                 {
                     Children =
                     {
-                        p1,
-                        p2
+                        p1.RegisterInNameScope(scope),
+                        p2.RegisterInNameScope(scope)
                     }
-                })
+                }.WithNameScope(scope))
             };
             target.ApplyTemplate();
 

+ 9 - 9
tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_InTemplate.cs

@@ -170,7 +170,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
         {
             var (target, _) = CreateTarget();
 
-            target.ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas());
+            target.ContentTemplate = new FuncDataTemplate<string>((_, __) => new Canvas());
             target.Content = "Foo";
 
             Assert.IsType<Canvas>(target.Child);
@@ -184,7 +184,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             target.Content = "Foo";
             Assert.IsType<TextBlock>(target.Child);
 
-            target.ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas());
+            target.ContentTemplate = new FuncDataTemplate<string>((_, __) => new Canvas());
             Assert.IsType<Canvas>(target.Child);
 
             target.ContentTemplate = null;
@@ -209,7 +209,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
         public void Recycles_DataTemplate()
         {
             var (target, _) = CreateTarget();
-            target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), true));
+            target.DataTemplates.Add(new FuncDataTemplate<string>((_, __) => new Border(), true));
 
             target.Content = "foo";
 
@@ -239,7 +239,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
         public void Detects_DataTemplate_Doesnt_Support_Recycling()
         {
             var (target, _) = CreateTarget();
-            target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), false));
+            target.DataTemplates.Add(new FuncDataTemplate<string>((_, __) => new Border(), false));
 
             target.Content = "foo";
 
@@ -256,7 +256,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             var (target, _) = CreateTarget();
 
             target.DataTemplates.Add(new FuncDataTemplate<string>(x => x == "bar", _ => new Canvas(), true));
-            target.DataTemplates.Add(new FuncDataTemplate<string>(_ => new Border(), true));
+            target.DataTemplates.Add(new FuncDataTemplate<string>((_, __) => new Border(), true));
 
             target.Content = "foo";
 
@@ -278,8 +278,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
             };
 
             var (target, host) = CreateTarget();
-            host.DataTemplates.Add(new FuncDataTemplate<string>(x => textBlock));
-            host.DataTemplates.Add(new FuncDataTemplate<int>(x => new Canvas()));
+            host.DataTemplates.Add(new FuncDataTemplate<string>((_, __) => textBlock));
+            host.DataTemplates.Add(new FuncDataTemplate<int>((_, __) => new Canvas()));
 
             target.Content = "foo";
             Assert.Same(textBlock, target.Child);
@@ -296,11 +296,11 @@ namespace Avalonia.Controls.UnitTests.Presenters
         {
             var templatedParent = new ContentControl
             {
-                Template = new FuncControlTemplate<ContentControl>(x => 
+                Template = new FuncControlTemplate<ContentControl>((_, s) => 
                     new ContentPresenter
                     {
                         Name = "PART_ContentPresenter",
-                    }),
+                    }.RegisterInNameScope(s).WithNameScope(s)),
             };
             var root = new TestRoot { Child = templatedParent };
 

+ 8 - 8
tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Standalone.cs

@@ -54,7 +54,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             var target = new ContentPresenter
             {
                 ContentTemplate =
-                    new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
+                    new FuncDataTemplate<string>((t, _) => new ContentControl() { Content = t }, false)
             };
 
             var parentMock = new Mock<Control>();
@@ -93,14 +93,14 @@ namespace Avalonia.Controls.UnitTests.Presenters
         {
             var contentControl = new ContentControl
             {
-                Template = new FuncControlTemplate<ContentControl>(c => new ContentPresenter()
+                Template = new FuncControlTemplate<ContentControl>((c, scope) => new ContentPresenter()
                 {
                     Name = "PART_ContentPresenter",
                     [~ContentPresenter.ContentProperty] = c[~ContentControl.ContentProperty],
                     [~ContentPresenter.ContentTemplateProperty] = c[~ContentControl.ContentTemplateProperty]
-                }),
+                }.RegisterInNameScope(scope).WithNameScope(scope)),
                 ContentTemplate =
-                    new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
+                    new FuncDataTemplate<string>((t, _) => new ContentControl() { Content = t }, false)
             };
 
             var parentMock = new Mock<Control>();
@@ -144,7 +144,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             var target = new ContentPresenter
             {
                 ContentTemplate =
-                    new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
+                    new FuncDataTemplate<string>((t, _) => new ContentControl() { Content = t }, false)
             };
 
             var parentMock = new Mock<Control>();
@@ -179,7 +179,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             var target = new ContentPresenter
             {
                 ContentTemplate =
-                    new FuncDataTemplate<string>(t => new ContentControl() { Content = t }, false)
+                    new FuncDataTemplate<string>((t, _) => new ContentControl() { Content = t }, false)
             };
 
             target.Content = "foo";
@@ -235,8 +235,8 @@ namespace Avalonia.Controls.UnitTests.Presenters
             {
                 DataTemplates =
                 {
-                    new FuncDataTemplate<string>(x => textBlock),
-                    new FuncDataTemplate<int>(x => new Canvas()),
+                    new FuncDataTemplate<string>((x, _) => textBlock),
+                    new FuncDataTemplate<int>((x, _) => new Canvas()),
                 },
             };
 

+ 2 - 2
tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Unrooted.cs

@@ -90,7 +90,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             {
                 DataTemplates =
                 {
-                    new FuncDataTemplate<string>(x => new Decorator()),
+                    new FuncDataTemplate<string>((x, _) => new Decorator()),
                 },
             };
 
@@ -99,4 +99,4 @@ namespace Avalonia.Controls.UnitTests.Presenters
             Assert.IsType<Decorator>(target.Child);
         }
     }
-}
+}

+ 1 - 1
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests.cs

@@ -220,7 +220,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             {
                 VirtualizationMode = ItemVirtualizationMode.None,
                 Items = items,
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Height = 10 }),
             };
 
             target.ApplyTemplate();

+ 1 - 1
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization.cs

@@ -309,7 +309,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
 
         private static IDataTemplate ItemTemplate()
         {
-            return new FuncDataTemplate<string>(x => new Canvas
+            return new FuncDataTemplate<string>((x, _) => new Canvas
             {
                 Width = 10,
                 Height = 10,

+ 4 - 4
tests/Avalonia.Controls.UnitTests/Presenters/ItemsPresenterTests_Virtualization_Simple.cs

@@ -470,7 +470,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
             {
                 VirtualizationMode = ItemVirtualizationMode.None,
                 Items = items,
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Height = 10 }),
             };
 
             target.ApplyTemplate();
@@ -1046,7 +1046,7 @@ namespace Avalonia.Controls.UnitTests.Presenters
 
         private static IDataTemplate StringDataTemplate()
         {
-            return new FuncDataTemplate<string>(x => new Canvas
+            return new FuncDataTemplate<string>((x, _) => new Canvas
             {
                 Width = 10,
                 Height = 10,
@@ -1095,12 +1095,12 @@ namespace Avalonia.Controls.UnitTests.Presenters
         {
             public TestContainer()
             {
-                Template = new FuncControlTemplate<TestContainer>(parent => new ContentPresenter
+                Template = new FuncControlTemplate<TestContainer>((parent, scope) => new ContentPresenter
                 {
                     Name = "PART_ContentPresenter",
                     [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
                     [~ContentPresenter.ContentTemplateProperty] = parent[~ContentControl.ContentTemplateProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
             }
         }
     }

+ 3 - 3
tests/Avalonia.Controls.UnitTests/Primitives/PopupRootTests.cs

@@ -134,12 +134,12 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var result = new PopupRoot
             {
-                Template = new FuncControlTemplate<PopupRoot>(parent =>
+                Template = new FuncControlTemplate<PopupRoot>((parent, scope) =>
                     new ContentPresenter
                     {
                         Name = "PART_ContentPresenter",
                         [!ContentPresenter.ContentProperty] = parent[!PopupRoot.ContentProperty],
-                    }),
+                    }.RegisterInNameScope(scope).WithNameScope(scope)),
             };
 
             result.ApplyTemplate();
@@ -154,7 +154,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
 
             public TemplatedControlWithPopup()
             {
-                Template = new FuncControlTemplate<TemplatedControlWithPopup>(parent =>
+                Template = new FuncControlTemplate<TemplatedControlWithPopup>((parent, _) =>
                     new Popup
                     {
                         [!Popup.ChildProperty] = parent[!TemplatedControlWithPopup.PopupContentProperty],

+ 4 - 4
tests/Avalonia.Controls.UnitTests/Primitives/PopupTests.cs

@@ -315,16 +315,16 @@ namespace Avalonia.Controls.UnitTests.Primitives
             return result;
         }
 
-        private static IControl PopupRootTemplate(PopupRoot control)
+        private static IControl PopupRootTemplate(PopupRoot control, INameScope scope)
         {
             return new ContentPresenter
             {
                 Name = "PART_ContentPresenter",
                 [~ContentPresenter.ContentProperty] = control[~ContentControl.ContentProperty],
-            };
+            }.RegisterInNameScope(scope).WithNameScope(scope);
         }
 
-        private static IControl PopupContentControlTemplate(PopupContentControl control)
+        private static IControl PopupContentControlTemplate(PopupContentControl control, INameScope scope)
         {
             return new Popup
             {
@@ -333,7 +333,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                 {
                     [~ContentPresenter.ContentProperty] = control[~ContentControl.ContentProperty],
                 }
-            };
+            }.RegisterInNameScope(scope).WithNameScope(scope);
         }
 
         private class PopupContentControl : ContentControl

+ 3 - 3
tests/Avalonia.Controls.UnitTests/Primitives/RangeBaseTests.cs

@@ -111,7 +111,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
 
             var target = new TestRange()
             {
-                Template = new FuncControlTemplate<RangeBase>(c =>
+                Template = new FuncControlTemplate<RangeBase>((c, scope) =>
                 {
                     track = new Track()
                     {
@@ -122,7 +122,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
 
                         Name = "PART_Track",
                         Thumb = new Thumb()
-                    };
+                    }.RegisterInNameScope(scope);
 
                     if (useXamlBinding)
                     {
@@ -138,7 +138,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                         track[~~Track.ValueProperty] = c[~~RangeBase.ValueProperty];
                     }
 
-                    return track;
+                    return track.WithNameScope(scope);
                 }),
                 Minimum = 0,
                 Maximum = 100,

+ 5 - 5
tests/Avalonia.Controls.UnitTests/Primitives/ScrollBarTests.cs

@@ -169,7 +169,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             Assert.False(target.IsVisible);
         }
 
-        private static Control Template(ScrollBar control)
+        private static Control Template(ScrollBar control, INameScope scope)
         {
             return new Border
             {
@@ -185,11 +185,11 @@ namespace Avalonia.Controls.UnitTests.Primitives
                     {
                         Template = new FuncControlTemplate<Thumb>(ThumbTemplate),
                     },
-                },
-            };
+                }.RegisterInNameScope(scope),
+            }.WithNameScope(scope);
         }
 
-        private static Control ThumbTemplate(Thumb control)
+        private static Control ThumbTemplate(Thumb control, INameScope scope)
         {
             return new Border
             {
@@ -197,4 +197,4 @@ namespace Avalonia.Controls.UnitTests.Primitives
             };
         }
     }
-}
+}

+ 2 - 2
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

@@ -896,13 +896,13 @@ namespace Avalonia.Controls.UnitTests.Primitives
 
         private FuncControlTemplate Template()
         {
-            return new FuncControlTemplate<SelectingItemsControl>(control =>
+            return new FuncControlTemplate<SelectingItemsControl>((control, scope) =>
                 new ItemsPresenter
                 {
                     Name = "itemsPresenter",
                     [~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
                     [~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private class Item : Control, ISelectable

+ 2 - 2
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_AutoSelect.cs

@@ -84,13 +84,13 @@ namespace Avalonia.Controls.UnitTests.Primitives
 
         private FuncControlTemplate Template()
         {
-            return new FuncControlTemplate<SelectingItemsControl>(control =>
+            return new FuncControlTemplate<SelectingItemsControl>((control, scope) =>
                 new ItemsPresenter
                 {
                     Name = "itemsPresenter",
                     [~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
                     [~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private class TestSelector : SelectingItemsControl

+ 5 - 5
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs

@@ -964,7 +964,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             {
                 Template = Template(),
                 Items = new[] { "Foo", "Bar", "Baz" },
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Width = 20, Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
                 SelectionMode = SelectionMode.Multiple,
             };
 
@@ -988,7 +988,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             {
                 Template = Template(),
                 Items = new[] { "Foo", "Bar", "Baz" },
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Width = 20, Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
                 SelectionMode = SelectionMode.Multiple,
             };
 
@@ -1010,7 +1010,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             {
                 Template = Template(),
                 Items = new[] { "Foo", "Bar", "Baz" },
-                ItemTemplate = new FuncDataTemplate<string>(x => new TextBlock { Width = 20, Height = 10 }),
+                ItemTemplate = new FuncDataTemplate<string>((x, _) => new TextBlock { Width = 20, Height = 10 }),
                 SelectionMode = SelectionMode.Multiple,
             };
 
@@ -1035,13 +1035,13 @@ namespace Avalonia.Controls.UnitTests.Primitives
 
         private FuncControlTemplate Template()
         {
-            return new FuncControlTemplate<SelectingItemsControl>(control =>
+            return new FuncControlTemplate<SelectingItemsControl>((control, scope) =>
                 new ItemsPresenter
                 {
                     Name = "PART_ItemsPresenter",
                     [~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
                     [~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private class TestSelector : SelectingItemsControl

+ 2 - 2
tests/Avalonia.Controls.UnitTests/Primitives/TabStripTests.cs

@@ -159,14 +159,14 @@ namespace Avalonia.Controls.UnitTests.Primitives
             Assert.Same("3rd", ((TabItem)target.SelectedItem).Name);
         }
 
-        private Control CreateTabStripTemplate(TabStrip parent)
+        private Control CreateTabStripTemplate(TabStrip parent, INameScope scope)
         {
             return new ItemsPresenter
             {
                 Name = "itemsPresenter",
                 [!ItemsPresenter.ItemsProperty] = parent[!ItemsControl.ItemsProperty],
                 [!ItemsPresenter.MemberSelectorProperty] = parent[!ItemsControl.MemberSelectorProperty],
-            };
+            }.RegisterInNameScope(scope).WithNameScope(scope);
         }
     }
 }

+ 29 - 29
tests/Avalonia.Controls.UnitTests/Primitives/TemplatedControlTests.cs

@@ -23,7 +23,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             bool executed = false;
 
-            var template = new FuncControlTemplate(_ =>
+            var template = new FuncControlTemplate((_, __) =>
             {
                 executed = true;
                 return new Control();
@@ -42,7 +42,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             bool executed = false;
 
-            var template = new FuncControlTemplate(_ =>
+            var template = new FuncControlTemplate((_, __) =>
             {
                 executed = true;
                 return new Control();
@@ -63,7 +63,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new Decorator
+                Template = new FuncControlTemplate((_, __) => new Decorator
                 {
                     Child = new Panel
                     {
@@ -97,7 +97,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new Decorator
+                Template = new FuncControlTemplate((_, __) => new Decorator
                 {
                     Child = new Panel
                     {
@@ -120,7 +120,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new Decorator
+                Template = new FuncControlTemplate((_, __) => new Decorator
                 {
                     Child = new Panel
                     {
@@ -149,7 +149,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new Decorator())
+                Template = new FuncControlTemplate((_, __) => new Decorator())
             };
 
             target.ApplyTemplate();
@@ -165,14 +165,14 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new Decorator())
+                Template = new FuncControlTemplate((_, __) => new Decorator())
             };
 
             target.ApplyTemplate();
 
             var child = (Decorator)target.GetVisualChildren().Single();
 
-            target.Template = new FuncControlTemplate(_ => new Canvas());
+            target.Template = new FuncControlTemplate((_, __) => new Canvas());
             target.ApplyTemplate();
 
             Assert.Null(child.Parent);
@@ -183,7 +183,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new ScrollViewer())
+                Template = new FuncControlTemplate((_, __) => new ScrollViewer())
             };
 
             target.ApplyTemplate();
@@ -203,7 +203,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                 {
                     Child = target = new TestTemplatedControl
                     {
-                        Template = new FuncControlTemplate(_ =>
+                        Template = new FuncControlTemplate((_, __) =>
                         {
                             return new StackPanel
                             {
@@ -232,11 +232,11 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TestTemplatedControl
             {
-                Template = new FuncControlTemplate(_ =>
+                Template = new FuncControlTemplate((_, __) =>
                 {
                     return new ContentControl
                     {
-                        Template = new FuncControlTemplate(parent =>
+                        Template = new FuncControlTemplate((parent, ___) =>
                         {
                             return new Border
                             {
@@ -311,7 +311,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TestTemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new Decorator())
+                Template = new FuncControlTemplate((_, __) => new Decorator())
             };
 
             var raised = false;
@@ -334,7 +334,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
         {
             var target = new TestTemplatedControl
             {
-                Template = new FuncControlTemplate(_ => new Decorator
+                Template = new FuncControlTemplate((_, __) => new Decorator
                 {
                     Child = new Border(),
                 })
@@ -348,7 +348,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             Assert.Equal(target, decorator.TemplatedParent);
             Assert.Equal(target, border.TemplatedParent);
 
-            target.Template = new FuncControlTemplate(_ => new Canvas());
+            target.Template = new FuncControlTemplate((_, __) => new Canvas());
 
             // Templated children should not be removed here: the control may be re-added
             // somewhere with the same template, so they could still be of use.
@@ -370,7 +370,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             {
                 Child = new TestTemplatedControl
                 {
-                    Template = new FuncControlTemplate(_ => new Decorator
+                    Template = new FuncControlTemplate((_, __) => new Decorator
                     {
                         Child = templateChild,
                     })
@@ -392,7 +392,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             {
                 Child = new TestTemplatedControl
                 {
-                    Template = new FuncControlTemplate(_ => new Decorator
+                    Template = new FuncControlTemplate((_, __) => new Decorator
                     {
                         Child = templateChild,
                     })
@@ -425,7 +425,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                             {
                                 new Setter(
                                     TemplatedControl.TemplateProperty,
-                                    new FuncControlTemplate(_ => new Decorator
+                                    new FuncControlTemplate((_, __) => new Decorator
                                     {
                                         Child = new Border(),
                                     }))
@@ -461,7 +461,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                             {
                                 new Setter(
                                     TemplatedControl.TemplateProperty,
-                                    new FuncControlTemplate(_ => new Decorator
+                                    new FuncControlTemplate((_, __) => new Decorator
                                     {
                                         Child = new Border(),
                                     }))
@@ -500,7 +500,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                             {
                                 new Setter(
                                     TemplatedControl.TemplateProperty,
-                                    new FuncControlTemplate(_ => new Decorator
+                                    new FuncControlTemplate((_, __) => new Decorator
                                     {
                                         Child = new Border(),
                                     }))
@@ -520,7 +520,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                             {
                                 new Setter(
                                     TemplatedControl.TemplateProperty,
-                                    new FuncControlTemplate(_ => new Decorator
+                                    new FuncControlTemplate((_, __) => new Decorator
                                     {
                                         Child = new Border(),
                                     }))
@@ -555,7 +555,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
                 {
                     Child = target = new TestTemplatedControl
                     {
-                        Template = new FuncControlTemplate(_ => new Decorator()),
+                        Template = new FuncControlTemplate((_, __) => new Decorator()),
                     }
                 };
 
@@ -573,7 +573,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
             }
         }
 
-        private static IControl ScrollingContentControlTemplate(ContentControl control)
+        private static IControl ScrollingContentControlTemplate(ContentControl control, INameScope scope)
         {
             return new Border
             {
@@ -585,20 +585,20 @@ namespace Avalonia.Controls.UnitTests.Primitives
                     {
                         Name = "PART_ContentPresenter",
                         [!ContentPresenter.ContentProperty] = control[!ContentControl.ContentProperty],
-                    }
-                }
-            };
+                    }.RegisterInNameScope(scope)
+                }.RegisterInNameScope(scope)
+            }.WithNameScope(scope);
         }
 
-        private static Control ScrollViewerTemplate(ScrollViewer control)
+        private static Control ScrollViewerTemplate(ScrollViewer control, INameScope scope)
         {
             var result = new ScrollContentPresenter
             {
                 Name = "PART_ContentPresenter",
                 [~ContentPresenter.ContentProperty] = control[~ContentControl.ContentProperty],
-            };
+            }.RegisterInNameScope(scope).WithNameScope(scope);
 
             return result;
         }
     }
-}
+}

+ 6 - 6
tests/Avalonia.Controls.UnitTests/ScrollViewerTests.cs

@@ -64,7 +64,7 @@ namespace Avalonia.Controls.UnitTests
             Assert.Equal(new Vector(10, 10), target.Offset);
         }
 
-        private Control CreateTemplate(ScrollViewer control)
+        private Control CreateTemplate(ScrollViewer control, INameScope scope)
         {
             return new Grid
             {
@@ -88,7 +88,7 @@ namespace Avalonia.Controls.UnitTests
                         [~~ScrollContentPresenter.OffsetProperty] = control[~~ScrollViewer.OffsetProperty],
                         [~~ScrollContentPresenter.ViewportProperty] = control[~~ScrollViewer.ViewportProperty],
                         [~ScrollContentPresenter.CanHorizontallyScrollProperty] = control[~ScrollViewer.CanHorizontallyScrollProperty],
-                    },
+                    }.RegisterInNameScope(scope),
                     new ScrollBar
                     {
                         Name = "horizontalScrollBar",
@@ -98,7 +98,7 @@ namespace Avalonia.Controls.UnitTests
                         [~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.HorizontalScrollBarViewportSizeProperty],
                         [~ScrollBar.VisibilityProperty] = control[~ScrollViewer.HorizontalScrollBarVisibilityProperty],
                         [Grid.RowProperty] = 1,
-                    },
+                    }.RegisterInNameScope(scope),
                     new ScrollBar
                     {
                         Name = "verticalScrollBar",
@@ -108,9 +108,9 @@ namespace Avalonia.Controls.UnitTests
                         [~ScrollBar.ViewportSizeProperty] = control[~ScrollViewer.VerticalScrollBarViewportSizeProperty],
                         [~ScrollBar.VisibilityProperty] = control[~ScrollViewer.VerticalScrollBarVisibilityProperty],
                         [Grid.ColumnProperty] = 1,
-                    },
+                    }.RegisterInNameScope(scope),
                 },
-            };
+            }.WithNameScope(scope);
         }
     }
-}
+}

+ 9 - 9
tests/Avalonia.Controls.UnitTests/TabControlTests.cs

@@ -129,7 +129,7 @@ namespace Avalonia.Controls.UnitTests
                 },
             };
 
-            var template = new FuncControlTemplate<TabItem>(x => new Decorator());
+            var template = new FuncControlTemplate<TabItem>((x, __) => new Decorator());
 
             using (UnitTestApplication.Start(TestServices.RealStyler))
             {
@@ -176,7 +176,7 @@ namespace Avalonia.Controls.UnitTests
                 DataContext = "Base",
                 DataTemplates =
                 {
-                    new FuncDataTemplate<Item>(x => new Button { Content = x })
+                    new FuncDataTemplate<Item>((x, __) => new Button { Content = x })
                 },
                 Items = items,
             };
@@ -273,7 +273,7 @@ namespace Avalonia.Controls.UnitTests
             TabControl target = new TabControl
             {
                 Template = TabControlTemplate(),
-                ContentTemplate = new FuncDataTemplate<string>(x =>
+                ContentTemplate = new FuncDataTemplate<string>((x, _) =>
                     new TextBlock { Tag = "bar", Text = x }),
                 Items = new[] { "Foo" },
             };
@@ -289,7 +289,7 @@ namespace Avalonia.Controls.UnitTests
 
         private IControlTemplate TabControlTemplate()
         {
-            return new FuncControlTemplate<TabControl>(parent =>
+            return new FuncControlTemplate<TabControl>((parent, scope) =>
                 new StackPanel
                 {
                     Children =
@@ -299,26 +299,26 @@ namespace Avalonia.Controls.UnitTests
                             Name = "PART_ItemsPresenter",
                             [!TabStrip.ItemsProperty] = parent[!TabControl.ItemsProperty],
                             [!TabStrip.ItemTemplateProperty] = parent[!TabControl.ItemTemplateProperty],
-                        },
+                        }.RegisterInNameScope(scope),
                         new ContentPresenter
                         {
                             Name = "PART_SelectedContentHost",
                             [!ContentPresenter.ContentProperty] = parent[!TabControl.SelectedContentProperty],
                             [!ContentPresenter.ContentTemplateProperty] = parent[!TabControl.SelectedContentTemplateProperty],
-                        }
+                        }.RegisterInNameScope(scope)
                     }
-                });
+                }.WithNameScope(scope));
         }
 
         private IControlTemplate TabItemTemplate()
         {
-            return new FuncControlTemplate<TabItem>(parent =>
+            return new FuncControlTemplate<TabItem>((parent, scope) =>
                 new ContentPresenter
                 {
                     Name = "PART_ContentPresenter",
                     [!ContentPresenter.ContentProperty] = parent[!TabItem.HeaderProperty],
                     [!ContentPresenter.ContentTemplateProperty] = parent[!TabItem.HeaderTemplateProperty]
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private void ApplyTemplate(TabControl target)

+ 2 - 2
tests/Avalonia.Controls.UnitTests/TextBoxTests.cs

@@ -456,7 +456,7 @@ namespace Avalonia.Controls.UnitTests
 
         private IControlTemplate CreateTemplate()
         {
-            return new FuncControlTemplate<TextBox>(control =>
+            return new FuncControlTemplate<TextBox>((control, scope) =>
                 new TextPresenter
                 {
                     Name = "PART_TextPresenter",
@@ -467,7 +467,7 @@ namespace Avalonia.Controls.UnitTests
                         Priority = BindingPriority.TemplatedParent,
                         RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent),
                     },
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private void RaiseKeyEvent(TextBox textBox, Key key, InputModifiers inputModifiers)

+ 2 - 2
tests/Avalonia.Controls.UnitTests/TextBoxTests_DataValidation.cs

@@ -93,7 +93,7 @@ namespace Avalonia.Controls.UnitTests
 
         private IControlTemplate CreateTemplate()
         {
-            return new FuncControlTemplate<TextBox>(control =>
+            return new FuncControlTemplate<TextBox>((control, scope) =>
                 new TextPresenter
                 {
                     Name = "PART_TextPresenter",
@@ -104,7 +104,7 @@ namespace Avalonia.Controls.UnitTests
                         Priority = BindingPriority.TemplatedParent,
                         RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent),
                     },
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private class ExceptionTest

+ 2 - 2
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs

@@ -226,12 +226,12 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate<TestTopLevel> CreateTemplate()
         {
-            return new FuncControlTemplate<TestTopLevel>(x =>
+            return new FuncControlTemplate<TestTopLevel>((x, scope) =>
                 new ContentPresenter
                 {
                     Name = "PART_ContentPresenter",
                     [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private class TestTopLevel : TopLevel

+ 9 - 9
tests/Avalonia.Controls.UnitTests/TreeViewTests.cs

@@ -50,7 +50,7 @@ namespace Avalonia.Controls.UnitTests
                     Template = CreateTreeViewTemplate(),
                     Items = CreateTestTreeData(),
                     ItemTemplate = new FuncTreeDataTemplate<Node>(
-                        _ => new Canvas(),
+                        (_, __) => new Canvas(),
                         x => x.Children),
                 }
             };
@@ -475,7 +475,7 @@ namespace Avalonia.Controls.UnitTests
                 DataContext = "Base",
                 DataTemplates =
                 {
-                    new FuncDataTemplate<Node>(x => new Button { Content = x })
+                    new FuncDataTemplate<Node>((x, _) => new Button { Content = x })
                 },
                 Items = items,
             };
@@ -513,7 +513,7 @@ namespace Avalonia.Controls.UnitTests
             Assert.Null(NameScope.GetNameScope((TreeViewItem)item));
         }
 
-        [Fact]
+        [Fact(Skip = "Is this behavior needed anymore?")]
         public void DataTemplate_Created_Item_Should_Be_NameScope()
         {
             var items = new object[]
@@ -799,16 +799,16 @@ namespace Avalonia.Controls.UnitTests
 
         private IControlTemplate CreateTreeViewTemplate()
         {
-            return new FuncControlTemplate<TreeView>(parent => new ItemsPresenter
+            return new FuncControlTemplate<TreeView>((parent, scope) => new ItemsPresenter
             {
                 Name = "PART_ItemsPresenter",
                 [~ItemsPresenter.ItemsProperty] = parent[~ItemsControl.ItemsProperty],
-            });
+            }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private IControlTemplate CreateTreeViewItemTemplate()
         {
-            return new FuncControlTemplate<TreeViewItem>(parent => new Panel
+            return new FuncControlTemplate<TreeViewItem>((parent, scope) => new Panel
             {
                 Children =
                 {
@@ -816,14 +816,14 @@ namespace Avalonia.Controls.UnitTests
                     {
                         Name = "PART_HeaderPresenter",
                         [~ContentPresenter.ContentProperty] = parent[~TreeViewItem.HeaderProperty],
-                    },
+                    }.RegisterInNameScope(scope),
                     new ItemsPresenter
                     {
                         Name = "PART_ItemsPresenter",
                         [~ItemsPresenter.ItemsProperty] = parent[~ItemsControl.ItemsProperty],
-                    }
+                    }.RegisterInNameScope(scope)
                 }
-            });
+            }.WithNameScope(scope));
         }
 
         private List<string> ExtractItemHeader(TreeView tree, int level)

+ 3 - 3
tests/Avalonia.Controls.UnitTests/UserControlTests.cs

@@ -40,7 +40,7 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate GetTemplate()
         {
-            return new FuncControlTemplate<UserControl>(parent =>
+            return new FuncControlTemplate<UserControl>((parent, scope) =>
             {
                 return new Border
                 {
@@ -49,8 +49,8 @@ namespace Avalonia.Controls.UnitTests
                     {
                         Name = "PART_ContentPresenter",
                         [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
-                    }
-                };
+                    }.RegisterInNameScope(scope)
+                }.WithNameScope(scope);
             });
         }
     }

+ 2 - 2
tests/Avalonia.Controls.UnitTests/Utils/HotKeyManagerTests.cs

@@ -59,13 +59,13 @@ namespace Avalonia.Controls.UnitTests.Utils
 
         private FuncControlTemplate CreateWindowTemplate()
         {
-            return new FuncControlTemplate<Window>(parent =>
+            return new FuncControlTemplate<Window>((parent, scope) =>
             {
                 return new ContentPresenter
                 {
                     Name = "PART_ContentPresenter",
                     [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
-                };
+                }.RegisterInNameScope(scope).WithNameScope(scope);
             });
         }
     }

+ 2 - 2
tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs

@@ -253,12 +253,12 @@ namespace Avalonia.Controls.UnitTests
 
         private FuncControlTemplate<TestWindowBase> CreateTemplate()
         {
-            return new FuncControlTemplate<TestWindowBase>(x =>
+            return new FuncControlTemplate<TestWindowBase>((x, scope) =>
                 new ContentPresenter
                 {
                     Name = "PART_ContentPresenter",
                     [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         private class TestWindowBase : WindowBase

+ 8 - 2
tests/Avalonia.Markup.UnitTests/Data/BindingTests_ElementName.cs

@@ -34,6 +34,8 @@ namespace Avalonia.Markup.UnitTests.Data
                 }
             };
 
+            root.RegisterChildrenNames();
+            
             var binding = new Binding
             {
                 ElementName = "source",
@@ -69,6 +71,7 @@ namespace Avalonia.Markup.UnitTests.Data
                     }
                 }
             };
+            root.RegisterChildrenNames();
 
             var binding = new Binding
             {
@@ -99,7 +102,8 @@ namespace Avalonia.Markup.UnitTests.Data
                     }
                 }
             };
-
+            root.RegisterChildrenNames();
+            
             var binding = new Binding
             {
                 ElementName = "source",
@@ -113,7 +117,7 @@ namespace Avalonia.Markup.UnitTests.Data
                 Name = "source",
                 Text = "foo",
             });
-
+            root.RegisterChildrenNames();
             Assert.Equal("foo", target.Text);
         }
 
@@ -136,6 +140,7 @@ namespace Avalonia.Markup.UnitTests.Data
                     }
                 }
             };
+            root.RegisterChildrenNames();
 
             var binding = new Binding
             {
@@ -151,6 +156,7 @@ namespace Avalonia.Markup.UnitTests.Data
             };
 
             stackPanel.Children.Add(source);
+            root.RegisterChildrenNames();
 
             Assert.Same(source, target.Content);
         }

+ 3 - 2
tests/Avalonia.Markup.UnitTests/Data/MultiBindingTests_Converters.cs

@@ -23,9 +23,10 @@ namespace Avalonia.Markup.UnitTests.Data
                 DataContext = new Class1(),
             };
 
+            var format = "{0:0.0} + {1:00}";
             var target = new MultiBinding
             {
-                StringFormat = "{0:0.0} + {1:00}",
+                StringFormat = format,
                 Bindings =
                 {
                     new Binding(nameof(Class1.Foo)),
@@ -35,7 +36,7 @@ namespace Avalonia.Markup.UnitTests.Data
 
             textBlock.Bind(TextBlock.TextProperty, target);
 
-            Assert.Equal("1.0 + 02", textBlock.Text);
+            Assert.Equal(string.Format(format, 1, 2), textBlock.Text);
         }
 
         [Fact]

+ 3 - 3
tests/Avalonia.Markup.UnitTests/Data/TemplateBindingTests.cs

@@ -18,7 +18,7 @@ namespace Avalonia.Markup.UnitTests.Data
         {
             var source = new Button
             {
-                Template = new FuncControlTemplate<Button>(parent =>
+                Template = new FuncControlTemplate<Button>((parent, _) =>
                     new ContentPresenter
                     {
                         [~ContentPresenter.ContentProperty] = new TemplateBinding(ContentControl.ContentProperty)
@@ -41,7 +41,7 @@ namespace Avalonia.Markup.UnitTests.Data
         {
             var source = new Button
             {
-                Template = new FuncControlTemplate<Button>(parent =>
+                Template = new FuncControlTemplate<Button>((parent, _) =>
                     new ContentPresenter
                     {
                         [~ContentPresenter.ContentProperty] = new TemplateBinding(ContentControl.ContentProperty)
@@ -67,7 +67,7 @@ namespace Avalonia.Markup.UnitTests.Data
         {
             var source = new Button
             {
-                Template = new FuncControlTemplate<Button>(parent =>
+                Template = new FuncControlTemplate<Button>((parent, _) =>
                     new ContentPresenter
                     {
                         [~ContentPresenter.ContentProperty] = new TemplateBinding(ContentControl.ContentProperty)

+ 2 - 2
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs

@@ -58,12 +58,12 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
                 {
                     new Setter(
                         Window.TemplateProperty,
-                        new FuncControlTemplate<Window>(x =>
+                        new FuncControlTemplate<Window>((x, scope) =>
                             new ContentPresenter
                             {
                                 Name = "PART_ContentPresenter",
                                 [!ContentPresenter.ContentProperty] = x[!Window.ContentProperty],
-                            }))
+                            }.RegisterInNameScope(scope).WithNameScope(scope)))
                 }
             };
         }

+ 2 - 2
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/DynamicResourceExtensionTests.cs

@@ -647,12 +647,12 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
                 {
                     new Setter(
                         Window.TemplateProperty,
-                        new FuncControlTemplate<Window>(x =>
+                        new FuncControlTemplate<Window>((x, scope) =>
                             new ContentPresenter
                             {
                                 Name = "PART_ContentPresenter",
                                 [!ContentPresenter.ContentProperty] = x[!Window.ContentProperty],
-                            }))
+                            }.RegisterInNameScope(scope).WithNameScope(scope)))
                 }
             };
         }

+ 2 - 2
tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs

@@ -534,12 +534,12 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
                 {
                     new Setter(
                         Window.TemplateProperty,
-                        new FuncControlTemplate<Window>(x =>
+                        new FuncControlTemplate<Window>((x, scope) =>
                             new ContentPresenter
                             {
                                 Name = "PART_ContentPresenter",
                                 [!ContentPresenter.ContentProperty] = x[!Window.ContentProperty],
-                            }))
+                            }.RegisterInNameScope(scope).WithNameScope(scope)))
                 }
             };
         }

+ 4 - 4
tests/Avalonia.ReactiveUI.UnitTests/AutoDataTemplateBindingHookTest.cs

@@ -98,7 +98,7 @@ namespace Avalonia.ReactiveUI.UnitTests
 
         private FuncControlTemplate GetTemplate()
         {
-            return new FuncControlTemplate<ItemsControl>(parent =>
+            return new FuncControlTemplate<ItemsControl>((parent, scope) =>
             {
                 return new Border
                 {
@@ -108,9 +108,9 @@ namespace Avalonia.ReactiveUI.UnitTests
                         Name = "PART_ItemsPresenter",
                         MemberSelector = parent.MemberSelector,
                         [~ItemsPresenter.ItemsProperty] = parent[~ItemsControl.ItemsProperty],
-                    }
-                };
+                    }.RegisterInNameScope(scope)
+                }.WithNameScope(scope);
             });
         }
     }
-}
+}

+ 4 - 4
tests/Avalonia.ReactiveUI.UnitTests/TransitioningContentControlTest.cs

@@ -45,7 +45,7 @@ namespace Avalonia.ReactiveUI.UnitTests
 
         private FuncControlTemplate GetTemplate()
         {
-            return new FuncControlTemplate<ContentControl>(parent =>
+            return new FuncControlTemplate<ContentControl>((parent, scope) =>
             {
                 return new Border
                 {
@@ -55,9 +55,9 @@ namespace Avalonia.ReactiveUI.UnitTests
                         Name = "PART_ContentPresenter",
                         [~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
                         [~ContentPresenter.ContentTemplateProperty] = parent[~ContentControl.ContentTemplateProperty],
-                    }
-                };
+                    }.RegisterInNameScope(scope)
+                }.WithNameScope(scope);
             });
         }
     }
-}
+}

+ 74 - 8
tests/Avalonia.Styling.UnitTests/ControlLocatorTests.cs

@@ -31,15 +31,19 @@ namespace Avalonia.Styling.UnitTests
                     }
                 }
             };
+            var scope = Register(root, relativeTo);
+            Register(root, target);
             
             var locator = ControlLocator.Track(relativeTo, "target");
             var result = await locator.Take(1);
 
             Assert.Same(target, result);
-            Assert.Equal(0, root.NameScopeRegisteredSubscribers);
-            Assert.Equal(0, root.NameScopeUnregisteredSubscribers);
+            Assert.Equal(0, scope.RegisteredSubscribers);
+            Assert.Equal(0, scope.UnregisteredSubscribers);
         }
 
+
+        
         [Fact]
         public void Track_By_Name_Should_Find_Control_Added_Later()
         {
@@ -59,6 +63,7 @@ namespace Avalonia.Styling.UnitTests
                     }
                 })
             };
+            var scope = Register(root, relativeTo);
 
             var locator = ControlLocator.Track(relativeTo, "target");
             var target = new TextBlock { Name = "target" };
@@ -67,11 +72,12 @@ namespace Avalonia.Styling.UnitTests
             using (locator.Subscribe(x => result.Add(x)))
             {
                 panel.Children.Add(target);
+                Register(root, target);
             }
 
             Assert.Equal(new[] { null, target }, result);
-            Assert.Equal(0, root.NameScopeRegisteredSubscribers);
-            Assert.Equal(0, root.NameScopeUnregisteredSubscribers);
+            Assert.Equal(0, scope.RegisteredSubscribers);
+            Assert.Equal(0, scope.UnregisteredSubscribers);
         }
 
         [Fact]
@@ -92,14 +98,18 @@ namespace Avalonia.Styling.UnitTests
                     }
                 }
             };
-
+            var scope = Register(root, target);
+            Register(root, relativeTo);
+            
             var locator = ControlLocator.Track(relativeTo, "target");
             var result = new List<ILogical>();
             locator.Subscribe(x => result.Add(x));
 
             var other = new TextBlock { Name = "target" };
             panel.Children.Remove(target);
+            scope.Unregister(target.Name);
             panel.Children.Add(other);
+            Register(root, other);
 
             Assert.Equal(new[] { target, null, other }, result);
         }
@@ -125,6 +135,9 @@ namespace Avalonia.Styling.UnitTests
                     }
                 }
             };
+            var scope1 = Register(root1, relativeTo);
+            Register(root1, relativeTo);
+            Register(root1, target1);
 
             var root2 = new TestRoot
             {
@@ -136,20 +149,73 @@ namespace Avalonia.Styling.UnitTests
                     }
                 }
             };
+            var scope2 = Register(root2, target2);
 
             var locator = ControlLocator.Track(relativeTo, "target");
-            var target = new TextBlock { Name = "target" };
             var result = new List<ILogical>();
 
             using (locator.Subscribe(x => result.Add(x)))
             {
                 ((StackPanel)root1.Child).Children.Remove(relativeTo);
+                scope1.Unregister(relativeTo.Name);
                 ((StackPanel)root2.Child).Children.Add(relativeTo);
+                Register(root2, relativeTo);
             }
 
             Assert.Equal(new[] { target1, null, target2 }, result);
-            Assert.Equal(0, root1.NameScopeRegisteredSubscribers);
-            Assert.Equal(0, root1.NameScopeUnregisteredSubscribers);
+            Assert.Equal(0, scope1.RegisteredSubscribers);
+            Assert.Equal(0, scope1.UnregisteredSubscribers);
+            Assert.Equal(0, scope2.RegisteredSubscribers);
+            Assert.Equal(0, scope2.UnregisteredSubscribers);
+        }
+
+        TrackingNameScope Register(StyledElement anchor, StyledElement element)
+        {
+            var scope = (TrackingNameScope)NameScope.GetNameScope(anchor);
+            if (scope == null)
+                NameScope.SetNameScope(anchor, scope = new TrackingNameScope());
+            NameScope.Register(anchor, element.Name, element);
+            return scope;
+        }
+        
+        class TrackingNameScope : INameScope
+        {
+            public int RegisteredSubscribers { get; private set; }
+            public int UnregisteredSubscribers { get; private set; }
+            private NameScope _inner = new NameScope();
+            public event EventHandler<NameScopeEventArgs> Registered
+            {
+                add
+                {
+                    _inner.Registered += value;
+                    RegisteredSubscribers++;
+                }
+                remove
+                {
+                    _inner.Registered -= value;
+                    RegisteredSubscribers--;
+                }
+            }
+
+            public event EventHandler<NameScopeEventArgs> Unregistered
+            {
+                add
+                {
+                    _inner.Unregistered += value;
+                    UnregisteredSubscribers++;
+                }
+                remove
+                {
+                    _inner.Unregistered -= value;
+                    UnregisteredSubscribers--;
+                }
+            }
+
+            public void Register(string name, object element) => _inner.Register(name, element);
+
+            public object Find(string name) => _inner.Find(name);
+
+            public void Unregister(string name) => _inner.Unregister(name);
         }
     }
 }

+ 6 - 6
tests/Avalonia.Styling.UnitTests/SelectorTests_Multiple.cs

@@ -16,12 +16,12 @@ namespace Avalonia.Styling.UnitTests
         [Fact]
         public void Named_Template_Child_Of_Control_With_Two_Classes()
         {
-            var template = new FuncControlTemplate(parent =>
+            var template = new FuncControlTemplate((parent, scope) =>
             {
                 return new Border
                 {
                     Name = "border",
-                };
+                }.RegisterInNameScope(scope).WithNameScope(scope);
             });
 
             var control = new Button
@@ -55,12 +55,12 @@ namespace Avalonia.Styling.UnitTests
         [Fact]
         public void Named_OfType_Template_Child_Of_Control_With_Two_Classes_Wrong_Type()
         {
-            var template = new FuncControlTemplate(parent =>
+            var template = new FuncControlTemplate((parent, scope) =>
             {
                 return new Border
                 {
                     Name = "border",
-                };
+                }.RegisterInNameScope(scope).WithNameScope(scope);
             });
 
             var control = new Button
@@ -88,12 +88,12 @@ namespace Avalonia.Styling.UnitTests
         [Fact]
         public void Named_Class_Template_Child_Of_Control()
         {
-            var template = new FuncControlTemplate(parent =>
+            var template = new FuncControlTemplate((parent, scope) =>
             {
                 return new Border
                 {
                     Name = "border",
-                };
+                }.RegisterInNameScope(scope).WithNameScope(scope);
             });
 
             var control = new Button

+ 0 - 13
tests/Avalonia.Styling.UnitTests/SetterTests.cs

@@ -51,19 +51,6 @@ namespace Avalonia.Styling.UnitTests
             Assert.IsType<Canvas>(control.Child);
         }
 
-        [Fact]
-        public void Materializes_Template_Should_Be_NameScope()
-        {
-            var control = new Decorator();
-            var template = new FuncTemplate<Canvas>(() => new Canvas());
-            var style = Mock.Of<IStyle>();
-            var setter = new Setter(Decorator.ChildProperty, template);
-
-            setter.Apply(style, control, null);
-
-            Assert.NotNull(NameScope.GetNameScope((Control)control.Child));
-        }
-
         [Fact]
         public void Does_Not_Call_Converter_ConvertBack_On_OneWay_Binding()
         {

+ 0 - 15
tests/Avalonia.Styling.UnitTests/StyledElementTests.cs

@@ -236,21 +236,6 @@ namespace Avalonia.Styling.UnitTests
             }
         }
 
-        [Fact]
-        public void Adding_To_Logical_Tree_Should_Register_With_NameScope()
-        {
-            using (AvaloniaLocator.EnterScope())
-            {
-                var root = new TestRoot();
-                var child = new Border();
-
-                child.Name = "foo";
-                root.Child = child;
-
-                Assert.Same(root.FindControl<Border>("foo"), child);
-            }
-        }
-
         [Fact]
         public void Name_Cannot_Be_Set_After_Added_To_Logical_Tree()
         {

+ 0 - 69
tests/Avalonia.Styling.UnitTests/StyledElementTests_NameScope.cs

@@ -1,69 +0,0 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-using Avalonia.UnitTests;
-using Xunit;
-
-namespace Avalonia.Controls.UnitTests
-{
-    public class StyledElementTests_NameScope
-    {
-        [Fact]
-        public void Controls_Should_Register_With_NameScope()
-        {
-            var root = new TestRoot
-            {
-                Child = new Border
-                {
-                    Name = "foo",
-                    Child = new Border
-                    {
-                        Name = "bar",
-                    }
-                }
-            };
-
-            root.ApplyTemplate();
-
-            Assert.Same(root.FindControl<Border>("foo"), root.Child);
-            Assert.Same(root.FindControl<Border>("bar"), ((Border)root.Child).Child);
-        }
-
-        [Fact]
-        public void Control_Should_Unregister_With_NameScope()
-        {
-            var root = new TestRoot
-            {
-                Child = new Border
-                {
-                    Name = "foo",
-                    Child = new Border
-                    {
-                        Name = "bar",
-                    }
-                }
-            };
-
-            root.Child = null;
-
-            Assert.Null(root.FindControl<Border>("foo"));
-            Assert.Null(root.FindControl<Border>("bar"));
-        }
-
-        [Fact]
-        public void Control_Should_Not_Register_With_Template_NameScope()
-        {
-            var root = new TestTemplatedRoot
-            {
-                Content = new Border
-                {
-                    Name = "foo",
-                }
-            };
-
-            root.ApplyTemplate();
-
-            Assert.Null(NameScope.GetNameScope((StyledElement)root.Presenter).Find("foo"));
-        }
-    }
-}

+ 2 - 2
tests/Avalonia.Styling.UnitTests/StyledElementTests_Resources.cs

@@ -222,12 +222,12 @@ namespace Avalonia.Controls.UnitTests
 
         private IControlTemplate ContentControlTemplate()
         {
-            return new FuncControlTemplate<ContentControl>(x =>
+            return new FuncControlTemplate<ContentControl>((x, scope) =>
                 new ContentPresenter
                 {
                     Name = "PART_ContentPresenter",
                     [!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
-                });
+                }.RegisterInNameScope(scope).WithNameScope(scope));
         }
     }
 }

+ 19 - 29
tests/Avalonia.UnitTests/TestRoot.cs

@@ -9,11 +9,12 @@ using Avalonia.Media;
 using Avalonia.Platform;
 using Avalonia.Rendering;
 using Avalonia.Styling;
+using Avalonia.VisualTree;
 using Moq;
 
 namespace Avalonia.UnitTests
 {
-    public class TestRoot : Decorator, IFocusScope, ILayoutRoot, IInputRoot, INameScope, IRenderRoot, IStyleRoot
+    public class TestRoot : Decorator, IFocusScope, ILayoutRoot, IInputRoot, IRenderRoot, IStyleRoot
     {
         private readonly NameScope _nameScope = new NameScope();
 
@@ -28,22 +29,6 @@ namespace Avalonia.UnitTests
             Child = child;
         }
 
-        event EventHandler<NameScopeEventArgs> INameScope.Registered
-        {
-            add { _nameScope.Registered += value; ++NameScopeRegisteredSubscribers; }
-            remove { _nameScope.Registered -= value; --NameScopeRegisteredSubscribers; }
-        }
-
-        public event EventHandler<NameScopeEventArgs> Unregistered
-        {
-            add { _nameScope.Unregistered += value; ++NameScopeUnregisteredSubscribers; }
-            remove { _nameScope.Unregistered -= value; --NameScopeUnregisteredSubscribers; }
-        }
-
-        public int NameScopeRegisteredSubscribers { get; private set; }
-
-        public int NameScopeUnregisteredSubscribers { get; private set; }
-
         public Size ClientSize { get; set; } = new Size(100, 100);
 
         public Size MaxClientSize { get; set; } = Size.Infinity;
@@ -94,19 +79,24 @@ namespace Avalonia.UnitTests
 
         public PixelPoint PointToScreen(Point p) => PixelPoint.FromPoint(p, 1);
 
-        void INameScope.Register(string name, object element)
+        public void RegisterChildrenNames()
         {
-            _nameScope.Register(name, element);
-        }
-
-        object INameScope.Find(string name)
-        {
-            return _nameScope.Find(name);
-        }
-
-        void INameScope.Unregister(string name)
-        {
-            _nameScope.Unregister(name);
+            var scope = NameScope.GetNameScope(this) ?? new NameScope();
+            NameScope.SetNameScope(this, scope);
+            void Visit(StyledElement element, bool force = false)
+            {
+                if (element.Name != null)
+                {
+                    if (scope.Find(element.Name) != element)
+                        NameScope.Register(this, element.Name, element);
+                }
+
+                if(element is IVisual visual && (force || NameScope.GetNameScope(element) == null))
+                    foreach(var child in visual.GetVisualChildren())
+                        if (child is StyledElement styledChild)
+                            Visit(styledChild);
+            }
+            Visit(this, true);
         }
     }
 }

+ 3 - 30
tests/Avalonia.UnitTests/TestTemplatedRoot.cs

@@ -12,28 +12,16 @@ using Avalonia.Styling;
 
 namespace Avalonia.UnitTests
 {
-    public class TestTemplatedRoot : ContentControl, ILayoutRoot, INameScope, IRenderRoot, IStyleRoot
+    public class TestTemplatedRoot : ContentControl, ILayoutRoot, IRenderRoot, IStyleRoot
     {
         private readonly NameScope _nameScope = new NameScope();
 
         public TestTemplatedRoot()
         {
-            Template = new FuncControlTemplate<TestTemplatedRoot>(x => new ContentPresenter
+            Template = new FuncControlTemplate<TestTemplatedRoot>((x, scope) => new ContentPresenter
             {
                 Name = "PART_ContentPresenter",
-            });
-        }
-
-        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; }
+            }.RegisterInNameScope(scope).WithNameScope(scope));
         }
 
         public Size ClientSize => new Size(100, 100);
@@ -63,20 +51,5 @@ namespace Avalonia.UnitTests
         public Point PointToClient(PixelPoint p) => p.ToPoint(1);
 
         public PixelPoint PointToScreen(Point p) => PixelPoint.FromPoint(p, 1);
-
-        void INameScope.Register(string name, object element)
-        {
-            _nameScope.Register(name, element);
-        }
-
-        object INameScope.Find(string name)
-        {
-            return _nameScope.Find(name);
-        }
-
-        void INameScope.Unregister(string name)
-        {
-            _nameScope.Unregister(name);
-        }
     }
 }