Browse Source

Fixed name scopes.

Controls were being registered with the nearest name scope on the visual
tree, whereas they should be registered by traversing the logical tree.
pull/335/head
Steven Kirk 11 years ago
parent
commit
9eb54f59d2
  1. 4
      src/Markup/Perspex.Markup.Xaml/Context/NameScopeWrapper.cs
  2. 10
      src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs
  3. 2
      src/Markup/Perspex.Markup/ControlLocator.cs
  4. 2
      src/Perspex.Base/PerspexProperty.cs
  5. 12
      src/Perspex.Controls/Button.cs
  6. 31
      src/Perspex.Controls/Control.cs
  7. 4
      src/Perspex.Controls/ControlExtensions.cs
  8. 2
      src/Perspex.Controls/Decorator.cs
  9. 2
      src/Perspex.Controls/INameScope.cs
  10. 8
      src/Perspex.Controls/NameScope.cs
  11. 2
      src/Perspex.Controls/NameScopeEventArgs.cs
  12. 2
      src/Perspex.Controls/NameScopeExtensions.cs
  13. 4
      src/Perspex.Controls/Perspex.Controls.csproj
  14. 5
      src/Perspex.Controls/Presenters/ContentPresenter.cs
  15. 2
      src/Perspex.Controls/Primitives/TemplatedControl.cs
  16. 4
      src/Perspex.SceneGraph/Perspex.SceneGraph.csproj
  17. 87
      src/Perspex.SceneGraph/Visual.cs
  18. 9
      src/Perspex.SceneGraph/VisualTreeAttachmentEventArgs.cs
  19. 125
      tests/Perspex.Controls.UnitTests/ControlTests_NameScope.cs
  20. 2
      tests/Perspex.Controls.UnitTests/NameScopeTests.cs
  21. 2
      tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj
  22. 2
      tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs
  23. 3
      tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj
  24. 31
      tests/Perspex.SceneGraph.UnitTests/TestRoot.cs
  25. 50
      tests/Perspex.SceneGraph.UnitTests/VisualTests.cs

4
src/Markup/Perspex.Markup.Xaml/Context/NameScopeWrapper.cs

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

10
src/Markup/Perspex.Markup.Xaml/Context/PerspexXamlType.cs

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

2
src/Markup/Perspex.Markup/ControlLocator.cs

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

2
src/Perspex.Base/PerspexProperty.cs

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

12
src/Perspex.Controls/Button.cs

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

31
src/Perspex.Controls/Control.cs

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

4
src/Perspex.Controls/ControlExtensions.cs

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

2
src/Perspex.Controls/Decorator.cs

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

2
src/Perspex.SceneGraph/INameScope.cs → src/Perspex.Controls/INameScope.cs

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

8
src/Perspex.SceneGraph/NameScope.cs → src/Perspex.Controls/NameScope.cs

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

2
src/Perspex.SceneGraph/NameScopeEventArgs.cs → src/Perspex.Controls/NameScopeEventArgs.cs

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

2
src/Perspex.SceneGraph/NameScopeExtensions.cs → src/Perspex.Controls/NameScopeExtensions.cs

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

4
src/Perspex.Controls/Perspex.Controls.csproj

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

5
src/Perspex.Controls/Presenters/ContentPresenter.cs

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

2
src/Perspex.Controls/Primitives/TemplatedControl.cs

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

4
src/Perspex.SceneGraph/Perspex.SceneGraph.csproj

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

87
src/Perspex.SceneGraph/Visual.cs

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

9
src/Perspex.SceneGraph/VisualTreeAttachmentEventArgs.cs

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

125
tests/Perspex.Controls.UnitTests/ControlTests_NameScope.cs

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

2
tests/Perspex.SceneGraph.UnitTests/NameScopeTests.cs → tests/Perspex.Controls.UnitTests/NameScopeTests.cs

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

2
tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj

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

2
tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs

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

3
tests/Perspex.SceneGraph.UnitTests/Perspex.SceneGraph.UnitTests.csproj

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

31
tests/Perspex.SceneGraph.UnitTests/TestRoot.cs

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

50
tests/Perspex.SceneGraph.UnitTests/VisualTests.cs

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

Loading…
Cancel
Save