Browse Source

Don't ApplyTemplate on nested templated controls...

...during ApplyTemplate. This was so that ItemsControls could their find
ItemsPresenters nested in other templated controls. Instead use
IItemsPresenterHost to make the presenter register itself with its
TemplatedParent.
pull/316/merge
Steven Kirk 10 years ago
parent
commit
c810f95904
  1. 15
      src/Perspex.Controls/ItemsControl.cs
  2. 29
      src/Perspex.Controls/Mixins/ContentControlMixin.cs
  3. 1
      src/Perspex.Controls/Perspex.Controls.csproj
  4. 6
      src/Perspex.Controls/Presenters/CarouselPresenter.cs
  5. 82
      src/Perspex.Controls/Presenters/ContentPresenter.cs
  6. 27
      src/Perspex.Controls/Presenters/IItemsPresenterHost.cs
  7. 6
      src/Perspex.Controls/Presenters/ItemsPresenter.cs
  8. 1
      src/Perspex.Controls/Primitives/PopupRoot.cs
  9. 15
      src/Perspex.Controls/Primitives/TemplatedControl.cs
  10. 2
      src/Perspex.Controls/ScrollViewer.cs
  11. 3
      tests/Perspex.Controls.UnitTests/CarouselTests.cs
  12. 38
      tests/Perspex.Controls.UnitTests/ContentControlTests.cs
  13. 1
      tests/Perspex.Controls.UnitTests/ControlTests_NameScope.cs
  14. 1
      tests/Perspex.Controls.UnitTests/HeaderedItemsControlTests .cs
  15. 11
      tests/Perspex.Controls.UnitTests/ItemsControlTests.cs
  16. 41
      tests/Perspex.Controls.UnitTests/ListBoxTests.cs
  17. 36
      tests/Perspex.Controls.UnitTests/ListBoxTests_Single.cs
  18. 12
      tests/Perspex.Controls.UnitTests/Presenters/CarouselPresenterTests.cs
  19. 47
      tests/Perspex.Controls.UnitTests/Presenters/ContentPresenterTests.cs
  20. 12
      tests/Perspex.Controls.UnitTests/Presenters/ItemsPresenterTests.cs
  21. 15
      tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs
  22. 14
      tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests_IScrollable.cs
  23. 7
      tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
  24. 4
      tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs
  25. 2
      tests/Perspex.Controls.UnitTests/Primitives/TabStripTests.cs
  26. 89
      tests/Perspex.Controls.UnitTests/Primitives/TemplatedControlTests.cs
  27. 24
      tests/Perspex.Controls.UnitTests/ScrollViewerTests.cs
  28. 17
      tests/Perspex.Controls.UnitTests/TabControlTests.cs
  29. 4
      tests/Perspex.Controls.UnitTests/TopLevelTests.cs
  30. 10
      tests/Perspex.Controls.UnitTests/TreeViewTests.cs
  31. 10
      tests/Perspex.Controls.UnitTests/Utils/HotKeyManagerTests.cs

15
src/Perspex.Controls/ItemsControl.cs

@ -21,7 +21,7 @@ namespace Perspex.Controls
/// <summary>
/// Displays a collection of items.
/// </summary>
public class ItemsControl : TemplatedControl
public class ItemsControl : TemplatedControl, IItemsPresenterHost
{
/// <summary>
/// The default value for the <see cref="ItemsPanel"/> property.
@ -127,6 +127,12 @@ namespace Perspex.Controls
protected set;
}
/// <inheritdoc/>
void IItemsPresenterHost.RegisterItemsPresenter(IItemsPresenter presenter)
{
Presenter = presenter;
}
/// <summary>
/// Gets the item at the specified index in a collection.
/// </summary>
@ -243,13 +249,6 @@ namespace Perspex.Controls
LogicalChildren.RemoveAll(toRemove);
}
/// <inheritdoc/>
protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
{
base.OnTemplateApplied(e);
Presenter = e.NameScope.Find<IItemsPresenter>("PART_ItemsPresenter");
}
/// <inheritdoc/>
protected override void OnTemplateChanged(PerspexPropertyChangedEventArgs e)
{

29
src/Perspex.Controls/Mixins/ContentControlMixin.cs

@ -8,6 +8,7 @@ using Perspex.Collections;
using Perspex.Controls.Presenters;
using Perspex.Controls.Primitives;
using Perspex.Interactivity;
using Perspex.Styling;
namespace Perspex.Controls.Mixins
{
@ -62,6 +63,7 @@ namespace Perspex.Controls.Mixins
var subscription = presenter
.GetObservable(ContentPresenter.ChildProperty)
.Subscribe(child => UpdateLogicalChild(
sender,
logicalChildren,
logicalChildren.FirstOrDefault(),
child));
@ -82,7 +84,18 @@ namespace Perspex.Controls.Mixins
if (sender != null)
{
var logicalChildren = logicalChildrenSelector(sender);
UpdateLogicalChild(logicalChildren, e.OldValue, e.NewValue);
UpdateLogicalChild(sender, logicalChildren, e.OldValue, e.NewValue);
}
});
Control.TemplatedParentProperty.Changed.Subscribe(e =>
{
var sender = e.Sender as TControl;
if (sender != null)
{
var logicalChild = logicalChildrenSelector(sender).FirstOrDefault() as IControl;
logicalChild?.SetValue(Control.TemplatedParentProperty, sender.TemplatedParent);
}
});
@ -111,24 +124,26 @@ namespace Perspex.Controls.Mixins
}
private static void UpdateLogicalChild(
IControl control,
IPerspexList<ILogical> logicalChildren,
object oldValue,
object newValue)
{
if (oldValue != newValue)
{
var logical = oldValue as ILogical;
var child = oldValue as IControl;
if (logical != null)
if (child != null)
{
logicalChildren.Remove(logical);
logicalChildren.Remove(child);
}
logical = newValue as ILogical;
child = newValue as IControl;
if (logical != null)
if (child != null)
{
logicalChildren.Add(logical);
child.SetValue(Control.TemplatedParentProperty, control.TemplatedParent);
logicalChildren.Add(child);
}
}
}

1
src/Perspex.Controls/Perspex.Controls.csproj

@ -57,6 +57,7 @@
<Compile Include="Platform\ITopLevelRenderer.cs" />
<Compile Include="Platform\IWindowingPlatform.cs" />
<Compile Include="Platform\PlatformManager.cs" />
<Compile Include="Presenters\IItemsPresenterHost.cs" />
<Compile Include="Primitives\HeaderedSelectingControl.cs" />
<Compile Include="Primitives\IScrollable.cs" />
<Compile Include="Primitives\TabStripItem.cs" />

6
src/Perspex.Controls/Presenters/CarouselPresenter.cs

@ -64,6 +64,7 @@ namespace Perspex.Controls.Presenters
static CarouselPresenter()
{
SelectedIndexProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.SelectedIndexChanged);
TemplatedParentProperty.Changed.AddClassHandler<CarouselPresenter>(x => x.TemplatedParentChanged);
}
/// <summary>
@ -256,5 +257,10 @@ namespace Perspex.Controls.Presenters
}
}
}
private void TemplatedParentChanged(PerspexPropertyChangedEventArgs e)
{
(e.NewValue as IItemsPresenterHost)?.RegisterItemsPresenter(this);
}
}
}

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

@ -57,12 +57,58 @@ namespace Perspex.Controls.Presenters
/// <inheritdoc/>
public override sealed void ApplyTemplate()
{
if (!_createdChild)
if (!_createdChild && ((ILogical)this).IsAttachedToLogicalTree)
{
CreateChild();
UpdateChild();
}
}
/// <summary>
/// Updates the <see cref="Child"/> control based on the control's <see cref="Content"/>.
/// </summary>
/// <remarks>
/// Usually the <see cref="Child"/> control is created automatically when
/// <see cref="ApplyTemplate"/> is called; however for this to happen, the control needs to
/// be attached to a logical tree (if the control is not attached to the logical tree, it
/// is reasonable to expect that the DataTemplates needed for the child are not yet
/// available). This method forces the <see cref="Child"/> control's creation at any point,
/// and is particularly useful in unit tests.
/// </remarks>
public void UpdateChild()
{
var old = Child;
var content = Content;
var result = this.MaterializeDataTemplate(content);
if (old != null)
{
VisualChildren.Remove(old);
}
if (result != null)
{
if (!(content is IControl))
{
result.DataContext = content;
}
Child = result;
if (result.Parent == null)
{
((ISetLogicalParent)result).SetParent((ILogical)this.TemplatedParent ?? this);
}
VisualChildren.Add(result);
}
else
{
Child = null;
}
_createdChild = true;
}
/// <inheritdoc/>
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
@ -100,37 +146,5 @@ namespace Perspex.Controls.Presenters
_createdChild = false;
InvalidateMeasure();
}
/// <summary>
/// Creates the <see cref="Child"/> control from the <see cref="Content"/>.
/// </summary>
private void CreateChild()
{
var old = Child;
var content = Content;
var result = this.MaterializeDataTemplate(content);
if (old != null)
{
VisualChildren.Remove(old);
}
if (result != null)
{
if (!(content is IControl))
{
result.DataContext = content;
}
Child = result;
VisualChildren.Add(result);
}
else
{
Child = null;
}
_createdChild = true;
}
}
}

27
src/Perspex.Controls/Presenters/IItemsPresenterHost.cs

@ -0,0 +1,27 @@
// 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 Perspex.Styling;
namespace Perspex.Controls.Presenters
{
/// <summary>
/// Represents a control which hosts an items presenter.
/// </summary>
/// <remarks>
/// This interface is implemented by <see cref="ItemsControl"/> which usually contains an
/// <see cref="ItemsPresenter"/> and exposes it through its
/// <see cref="ItemsControl.Presenter"/> property. ItemsPresenters can be within
/// nested templates or in popups and so are not necessarily created immediately when the
/// parent control's template is instantiated so they register themselves using this
/// interface.
/// </remarks>
public interface IItemsPresenterHost : ITemplatedControl
{
/// <summary>
/// Registers an <see cref="IItemsPresenter"/> with a host control.
/// </summary>
/// <param name="presenter">The items presenter.</param>
void RegisterItemsPresenter(IItemsPresenter presenter);
}
}

6
src/Perspex.Controls/Presenters/ItemsPresenter.cs

@ -49,6 +49,7 @@ namespace Perspex.Controls.Presenters
typeof(ItemsPresenter),
KeyboardNavigationMode.Once);
ItemsProperty.Changed.AddClassHandler<ItemsPresenter>(x => x.ItemsChanged);
TemplatedParentProperty.Changed.AddClassHandler<ItemsPresenter>(x => x.TemplatedParentChanged);
}
/// <summary>
@ -270,6 +271,11 @@ namespace Perspex.Controls.Presenters
}
}
private void TemplatedParentChanged(PerspexPropertyChangedEventArgs e)
{
(e.NewValue as IItemsPresenterHost)?.RegisterItemsPresenter(this);
}
private void AddContainers(IEnumerable<ItemContainer> items)
{
foreach (var i in items)

1
src/Perspex.Controls/Primitives/PopupRoot.cs

@ -96,6 +96,7 @@ namespace Perspex.Controls.Primitives
_presenterSubscription = null;
}
Presenter?.ApplyTemplate();
Presenter?.GetObservable(ContentPresenter.ChildProperty)
.Subscribe(SetTemplatedParentAndApplyChildTemplates);
}

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

@ -212,20 +212,9 @@ namespace Perspex.Controls.Primitives
var child = Template.Build(this);
var nameScope = new NameScope();
NameScope.SetNameScope((Control)child, nameScope);
// We need to call SetupTemplateControls twice:
// - Once before the controls are added to the visual/logical trees so that the
// TemplatedParent property is set and names are registered; if
// TemplatedParent is not set when the control is added to the logical tree,
// then styles with the /template/ selector won't match.
// - Once after the controls are added to the logical tree (and thus styled) to
// call ApplyTemplate on nested templated controls and register any of our
// templated children that appear as children of presenters in these nested
// templated child controls.
SetupTemplateControls(child, nameScope);
VisualChildren.Add(child);
((ISetLogicalParent)child).SetParent(this);
SetupTemplateControls(child, nameScope);
VisualChildren.Add(child);
OnTemplateApplied(new TemplateAppliedEventArgs(nameScope));
}
@ -290,8 +279,6 @@ namespace Perspex.Controls.Primitives
}
}
control.ApplyTemplate();
if (!(control is IPresenter && control.TemplatedParent == this))
{
foreach (IControl child in control.GetVisualChildren())

2
src/Perspex.Controls/ScrollViewer.cs

@ -120,8 +120,6 @@ namespace Perspex.Controls
nameof(VerticalScrollBarVisibility),
ScrollBarVisibility.Auto);
private IDisposable _scrollableSubscription;
/// <summary>
/// Initializes static members of the <see cref="ScrollViewer"/> class.
/// </summary>

3
tests/Perspex.Controls.UnitTests/CarouselTests.cs

@ -45,6 +45,7 @@ namespace Perspex.Controls.UnitTests
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Equal(1, target.GetLogicalChildren().Count());
@ -57,7 +58,7 @@ namespace Perspex.Controls.UnitTests
{
return new CarouselPresenter
{
Name = "itemsPresenter",
Name = "PART_ItemsPresenter",
[~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
[~CarouselPresenter.SelectedIndexProperty] = control[~SelectingItemsControl.SelectedIndexProperty],

38
tests/Perspex.Controls.UnitTests/ContentControlTests.cs

@ -27,8 +27,8 @@ namespace Perspex.Controls.UnitTests
var target = new ContentControl();
target.Content = "Foo";
target.Template = GetTemplate();
target.Measure(new Size(100, 100));
target.ApplyTemplate();
target.Presenter.UpdateChild();
var child = ((IVisual)target).VisualChildren.Single();
Assert.IsType<Border>(child);
@ -54,6 +54,7 @@ namespace Perspex.Controls.UnitTests
root.Child = target;
target.ApplyTemplate();
target.Presenter.UpdateChild();
styler.Verify(x => x.ApplyStyles(It.IsAny<ContentControl>()), Times.Once());
styler.Verify(x => x.ApplyStyles(It.IsAny<Border>()), Times.Once());
@ -71,6 +72,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Content = child;
target.ApplyTemplate();
target.Presenter.UpdateChild();
var contentPresenter = child.GetVisualParent<ContentPresenter>();
Assert.Equal(target, contentPresenter.TemplatedParent);
@ -85,6 +87,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Content = child;
target.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.Null(child.TemplatedParent);
}
@ -115,6 +118,7 @@ namespace Perspex.Controls.UnitTests
target.Content = "Foo";
target.ApplyTemplate();
target.Presenter.UpdateChild();
var child = target.Presenter.Child;
@ -131,6 +135,9 @@ namespace Perspex.Controls.UnitTests
var child = new Control();
target.Content = child;
Assert.Equal(new[] { child }, target.GetLogicalChildren());
target.Content = null;
Assert.Null(child.Parent);
@ -151,7 +158,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Content = child;
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.True(called);
}
@ -166,11 +173,12 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Content = child;
target.ApplyTemplate();
target.Presenter.UpdateChild();
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true;
target.Content = null;
target.Presenter.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.True(called);
}
@ -178,19 +186,20 @@ namespace Perspex.Controls.UnitTests
[Fact]
public void Changing_Content_Should_Fire_LogicalChildren_CollectionChanged()
{
var contentControl = new ContentControl();
var target = new ContentControl();
var child1 = new Control();
var child2 = new Control();
var called = false;
contentControl.Template = GetTemplate();
contentControl.Content = child1;
contentControl.ApplyTemplate();
target.Template = GetTemplate();
target.Content = child1;
target.ApplyTemplate();
target.Presenter.UpdateChild();
((ILogical)contentControl).LogicalChildren.CollectionChanged += (s, e) => called = true;
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) => called = true;
contentControl.Content = child2;
contentControl.Presenter.ApplyTemplate();
target.Content = child2;
target.Presenter.ApplyTemplate();
Assert.True(called);
}
@ -202,12 +211,13 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.ApplyTemplate();
target.Presenter.UpdateChild();
target.Content = "Foo";
target.Presenter.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.Equal("Foo", ((TextBlock)target.Presenter.Child).Text);
target.Content = "Bar";
target.Presenter.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.Equal("Bar", ((TextBlock)target.Presenter.Child).Text);
}
@ -219,6 +229,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Content = "Foo";
target.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.Equal("Foo", target.Presenter.Child.DataContext);
}
@ -231,6 +242,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Content = new TextBlock();
target.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.Null(target.Presenter.Child.DataContext);
}

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

@ -28,6 +28,7 @@ namespace Perspex.Controls.UnitTests
};
root.ApplyTemplate();
root.Presenter.UpdateChild();
Assert.Same(root.Find("foo"), root.Content);
Assert.Same(root.Find("bar"), ((Border)root.Content).Child);

1
tests/Perspex.Controls.UnitTests/HeaderedItemsControlTests .cs

@ -37,6 +37,7 @@ namespace Perspex.Controls.UnitTests
target.Header = "Foo";
target.ApplyTemplate();
target.HeaderPresenter.UpdateChild();
var child = target.HeaderPresenter.Child;

11
tests/Perspex.Controls.UnitTests/ItemsControlTests.cs

@ -22,6 +22,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Items = new[] { "Foo" };
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.Equal(target, target.Presenter.Panel.TemplatedParent);
}
@ -34,6 +35,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Items = new[] { "Foo" };
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
var item = (TextBlock)target.Presenter.Panel.GetVisualChildren().First();
@ -125,6 +127,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Items = new[] { "Foo" };
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
var logical = (ILogical)target;
Assert.Equal(1, logical.LogicalChildren.Count);
@ -140,6 +143,10 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Items = new[] { "Foo" };
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.NotEmpty(target.GetLogicalChildren());
target.Items = null;
Assert.Equal(new ILogical[0], target.GetLogicalChildren());
@ -210,6 +217,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Items = items;
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
called = e.Action == NotifyCollectionChangedAction.Add;
@ -229,6 +237,7 @@ namespace Perspex.Controls.UnitTests
target.Template = GetTemplate();
target.Items = items;
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
((ILogical)target).LogicalChildren.CollectionChanged += (s, e) =>
called = e.Action == NotifyCollectionChangedAction.Remove;
@ -339,6 +348,7 @@ namespace Perspex.Controls.UnitTests
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
var dataContexts = target.Presenter.Panel.Children
.Cast<Control>()
@ -361,6 +371,7 @@ namespace Perspex.Controls.UnitTests
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
var text = target.Presenter.Panel.Children
.Cast<TextBlock>()

41
tests/Perspex.Controls.UnitTests/ListBoxTests.cs

@ -7,12 +7,26 @@ using Perspex.Controls.Templates;
using Perspex.Input;
using Perspex.LogicalTree;
using Perspex.Styling;
using Perspex.VisualTree;
using Xunit;
namespace Perspex.Controls.UnitTests
{
public class ListBoxTests
{
[Fact]
public void ListBox_Should_Find_ItemsPresenter_In_ScrollViewer()
{
var target = new ListBox
{
Template = new FuncControlTemplate(CreateListBoxTemplate),
};
ApplyTemplate(target);
Assert.IsType<ItemsPresenter>(target.Presenter);
}
[Fact]
public void ListBoxItem_Containers_Should_Be_Generated()
{
@ -23,12 +37,12 @@ namespace Perspex.Controls.UnitTests
Items = items,
};
target.ApplyTemplate();
ApplyTemplate(target);
var text = target.Presenter.Panel.Children
.OfType<ListBoxItem>()
.Do(x => x.Template = ListBoxItemTemplate())
.Do(x => x.ApplyTemplate())
.Do(x => { x.ApplyTemplate(); x.Presenter.UpdateChild(); })
.Select(x => x.Presenter.Child)
.OfType<TextBlock>()
.Select(x => x.Text)
@ -46,7 +60,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplate(target);
Assert.Equal(3, target.GetLogicalChildren().Count());
@ -78,7 +92,7 @@ namespace Perspex.Controls.UnitTests
Items = items,
};
target.ApplyTemplate();
ApplyTemplate(target);
var dataContexts = target.Presenter.Panel.Children
.Cast<Control>()
@ -99,7 +113,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplate(target);
target.Presenter.Panel.Children[1].RaiseEvent(new PointerPressEventArgs
{
@ -140,10 +154,27 @@ namespace Perspex.Controls.UnitTests
{
return new ScrollContentPresenter
{
Name = "PART_ContentPresenter",
[~ContentPresenter.ContentProperty] = parent.GetObservable(ContentControl.ContentProperty),
};
}
private void ApplyTemplate(ListBox target)
{
// Apply the template to the ListBox itself.
target.ApplyTemplate();
// Then to its inner ScrollViewer.
var scrollViewer = (ScrollViewer)target.GetVisualChildren().Single();
scrollViewer.ApplyTemplate();
// Then make the ScrollViewer create its child.
scrollViewer.Presenter.UpdateChild();
// Now the ItemsPresenter should be reigstered, so apply its template.
target.Presenter.ApplyTemplate();
}
private class Item
{
public Item(string value)

36
tests/Perspex.Controls.UnitTests/ListBoxTests_Single.cs

@ -7,6 +7,7 @@ using Perspex.Controls.Templates;
using Perspex.Input;
using Perspex.LogicalTree;
using Perspex.Styling;
using Perspex.VisualTree;
using Xunit;
namespace Perspex.Controls.UnitTests
@ -22,7 +23,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplate(target);
target.Presenter.Panel.Children[0].RaiseEvent(new GotFocusEventArgs
{
@ -42,7 +43,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplate(target);
target.Presenter.Panel.Children[0].RaiseEvent(new GotFocusEventArgs
{
@ -62,7 +63,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplate(target);
target.Presenter.Panel.Children[0].RaiseEvent(new PointerPressEventArgs
{
@ -82,7 +83,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplate(target);
target.SelectedIndex = 0;
target.Presenter.Panel.Children[0].RaiseEvent(new PointerPressEventArgs
@ -104,7 +105,7 @@ namespace Perspex.Controls.UnitTests
SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
};
target.ApplyTemplate();
ApplyTemplate(target);
target.Presenter.Panel.Children[0].RaiseEvent(new PointerPressEventArgs
{
@ -125,7 +126,7 @@ namespace Perspex.Controls.UnitTests
SelectionMode = SelectionMode.Toggle,
};
target.ApplyTemplate();
ApplyTemplate(target);
target.SelectedIndex = 0;
target.Presenter.Panel.Children[0].RaiseEvent(new PointerPressEventArgs
@ -147,7 +148,7 @@ namespace Perspex.Controls.UnitTests
SelectionMode = SelectionMode.Toggle | SelectionMode.AlwaysSelected,
};
target.ApplyTemplate();
ApplyTemplate(target);
target.SelectedIndex = 0;
target.Presenter.Panel.Children[0].RaiseEvent(new PointerPressEventArgs
@ -169,7 +170,7 @@ namespace Perspex.Controls.UnitTests
SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
};
target.ApplyTemplate();
ApplyTemplate(target);
target.SelectedIndex = 1;
target.Presenter.Panel.Children[0].RaiseEvent(new PointerPressEventArgs
@ -190,7 +191,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplate(target);
((ListBoxItem)target.GetLogicalChildren().ElementAt(1)).IsSelected = true;
@ -215,10 +216,27 @@ namespace Perspex.Controls.UnitTests
{
return new ScrollContentPresenter
{
Name = "PART_ContentPresenter",
[~ContentPresenter.ContentProperty] = parent.GetObservable(ContentControl.ContentProperty),
};
}
private void ApplyTemplate(ListBox target)
{
// Apply the template to the ListBox itself.
target.ApplyTemplate();
// Then to its inner ScrollViewer.
var scrollViewer = (ScrollViewer)target.GetVisualChildren().Single();
scrollViewer.ApplyTemplate();
// Then make the ScrollViewer create its child.
scrollViewer.Presenter.UpdateChild();
// Now the ItemsPresenter should be reigstered, so apply its template.
target.Presenter.ApplyTemplate();
}
private class Item
{
public Item(string value)

12
tests/Perspex.Controls.UnitTests/Presenters/CarouselPresenterTests.cs

@ -1,6 +1,7 @@
// 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 Moq;
using Perspex.Controls.Generators;
using Perspex.Controls.Presenters;
using Perspex.Controls.Templates;
@ -10,6 +11,17 @@ namespace Perspex.Controls.UnitTests.Presenters
{
public class CarouselPresenterTests
{
[Fact]
public void Should_Register_With_Host_When_TemplatedParent_Set()
{
var host = new Mock<IItemsPresenterHost>();
var target = new CarouselPresenter();
target.SetValue(Control.TemplatedParentProperty, host.Object);
host.Verify(x => x.RegisterItemsPresenter(target));
}
[Fact]
public void ApplyTemplate_Should_Create_Panel()
{

47
tests/Perspex.Controls.UnitTests/Presenters/ContentPresenterTests.cs

@ -1,8 +1,11 @@
// 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.Linq;
using Perspex.Controls.Presenters;
using Perspex.Controls.Primitives;
using Perspex.Controls.Templates;
using Perspex.VisualTree;
using Xunit;
namespace Perspex.Controls.UnitTests.Presenters
@ -17,11 +20,8 @@ namespace Perspex.Controls.UnitTests.Presenters
target.Content = child;
// Child should not update until ApplyTemplate called.
Assert.Null(target.Child);
target.ApplyTemplate();
target.UpdateChild();
Assert.Equal(child, target.Child);
}
@ -32,13 +32,39 @@ namespace Perspex.Controls.UnitTests.Presenters
target.Content = "Foo";
// Child should not update until ApplyTemplate called.
Assert.Null(target.Child);
target.UpdateChild();
Assert.IsType<TextBlock>(target.Child);
Assert.Equal("Foo", ((TextBlock)target.Child).Text);
}
[Fact]
public void Should_Set_Childs_Parent_To_TemplatedParent()
{
var content = new Border();
var target = new TestContentControl
{
Template = new FuncControlTemplate<TestContentControl>(parent =>
new ContentPresenter { Content = parent.Child }),
Child = content,
};
target.ApplyTemplate();
var presenter = ((ContentPresenter)target.GetVisualChildren().Single());
presenter.UpdateChild();
Assert.IsType<TextBlock>(target.Child);
Assert.Equal("Foo", ((TextBlock)target.Child).Text);
Assert.Same(target, content.Parent);
}
[Fact]
public void Should_Set_Childs_Parent_To_Itself_Outside_Template()
{
var content = new Border();
var target = new ContentPresenter { Content = content };
target.UpdateChild();
Assert.Same(target, content.Parent);
}
[Fact]
@ -49,7 +75,7 @@ namespace Perspex.Controls.UnitTests.Presenters
Content = "Foo",
};
target.ApplyTemplate();
target.UpdateChild();
Assert.IsType<TextBlock>(target.Child);
var root = new TestRoot
@ -64,5 +90,10 @@ namespace Perspex.Controls.UnitTests.Presenters
target.ApplyTemplate();
Assert.IsType<Decorator>(target.Child);
}
private class TestContentControl : TemplatedControl
{
public IControl Child { get; set; }
}
}
}

12
tests/Perspex.Controls.UnitTests/Presenters/ItemsPresenterTests.cs

@ -3,6 +3,7 @@
using System.Collections.ObjectModel;
using System.Linq;
using Moq;
using Perspex.Collections;
using Perspex.Controls.Generators;
using Perspex.Controls.Presenters;
@ -15,6 +16,17 @@ namespace Perspex.Controls.UnitTests.Presenters
{
public class ItemsPresenterTests
{
[Fact]
public void Should_Register_With_Host_When_TemplatedParent_Set()
{
var host = new Mock<IItemsPresenterHost>();
var target = new ItemsPresenter();
target.SetValue(Control.TemplatedParentProperty, host.Object);
host.Verify(x => x.RegisterItemsPresenter(target));
}
[Fact]
public void Should_Add_Containers()
{

15
tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests.cs

@ -25,6 +25,7 @@ namespace Perspex.Controls.UnitTests.Presenters
},
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -43,6 +44,7 @@ namespace Perspex.Controls.UnitTests.Presenters
},
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -62,6 +64,7 @@ namespace Perspex.Controls.UnitTests.Presenters
},
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -81,6 +84,7 @@ namespace Perspex.Controls.UnitTests.Presenters
},
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -101,6 +105,7 @@ namespace Perspex.Controls.UnitTests.Presenters
},
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -116,6 +121,7 @@ namespace Perspex.Controls.UnitTests.Presenters
Content = content = new TestControl(),
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -136,6 +142,7 @@ namespace Perspex.Controls.UnitTests.Presenters
Offset = new Vector(25, 25),
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -152,6 +159,7 @@ namespace Perspex.Controls.UnitTests.Presenters
[ScrollContentPresenter.CanScrollHorizontallyProperty] = false,
};
target.UpdateChild();
target.Measure(new Size(100, 100));
Assert.Equal(new Size(100, double.PositiveInfinity), child.AvailableSize);
@ -166,6 +174,7 @@ namespace Perspex.Controls.UnitTests.Presenters
Content = child,
};
target.UpdateChild();
target.Measure(new Size(100, 100));
Assert.Equal(Size.Infinity, child.AvailableSize);
@ -181,6 +190,7 @@ namespace Perspex.Controls.UnitTests.Presenters
var set = new List<string>();
target.UpdateChild();
target.Measure(new Size(100, 100));
target.GetObservable(ScrollViewer.ViewportProperty).Skip(1).Subscribe(_ => set.Add("Viewport"));
@ -199,6 +209,7 @@ namespace Perspex.Controls.UnitTests.Presenters
Content = new Border { Width = 140, Height = 150 }
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
target.Offset = new Vector(10, 100);
@ -232,7 +243,7 @@ namespace Perspex.Controls.UnitTests.Presenters
}
};
target.ApplyTemplate();
target.UpdateChild();
target.Measure(Size.Infinity);
target.Arrange(new Rect(0, 0, 100, 100));
target.BringDescendentIntoView(target.Child, new Rect(200, 200, 0, 0));
@ -259,7 +270,7 @@ namespace Perspex.Controls.UnitTests.Presenters
}
};
target.ApplyTemplate();
target.UpdateChild();
target.Measure(Size.Infinity);
target.Arrange(new Rect(0, 0, 100, 100));
target.BringDescendentIntoView(border, new Rect(200, 200, 0, 0));

14
tests/Perspex.Controls.UnitTests/Presenters/ScrollContentPresenterTests_IScrollable.cs

@ -20,6 +20,7 @@ namespace Perspex.Controls.UnitTests
Content = scrollable,
};
target.UpdateChild();
target.Measure(new Size(100, 100));
Assert.Equal(new Size(100, 100), scrollable.AvailableSize);
@ -40,6 +41,7 @@ namespace Perspex.Controls.UnitTests
Content = scrollable,
};
target.UpdateChild();
target.Measure(new Size(100, 100));
target.Arrange(new Rect(0, 0, 100, 100));
@ -56,6 +58,7 @@ namespace Perspex.Controls.UnitTests
var changed = false;
target.UpdateChild();
target.Measure(new Size(100, 100));
target.GetObservable(ScrollViewer.ViewportProperty).Skip(1).Subscribe(_ => changed = true);
@ -75,7 +78,7 @@ namespace Perspex.Controls.UnitTests
Content = scrollable
};
target.ApplyTemplate();
target.UpdateChild();
Assert.NotNull(scrollable.InvalidateScroll);
}
@ -89,9 +92,9 @@ namespace Perspex.Controls.UnitTests
Content = scrollable
};
target.ApplyTemplate();
target.UpdateChild();
target.Content = null;
target.ApplyTemplate();
target.UpdateChild();
Assert.Null(scrollable.InvalidateScroll);
}
@ -111,7 +114,7 @@ namespace Perspex.Controls.UnitTests
Content = scrollable
};
target.ApplyTemplate();
target.UpdateChild();
Assert.Equal(scrollable.Extent, target.Extent);
Assert.Equal(scrollable.Offset, target.Offset);
@ -140,8 +143,7 @@ namespace Perspex.Controls.UnitTests
Content = scrollable
};
target.ApplyTemplate();
target.UpdateChild();
target.Offset = new Vector(25, 25);
Assert.Equal(target.Offset, scrollable.Offset);

7
tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

@ -6,7 +6,6 @@ using Perspex.Collections;
using Perspex.Controls.Presenters;
using Perspex.Controls.Primitives;
using Perspex.Controls.Templates;
using Perspex.Input;
using Perspex.Interactivity;
using Xunit;
@ -69,6 +68,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedItem = items[1];
Assert.False(items[0].IsSelected);
@ -92,6 +92,7 @@ namespace Perspex.Controls.UnitTests.Primitives
target.SelectedItem = items[1];
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.False(items[0].IsSelected);
Assert.True(items[1].IsSelected);
@ -114,6 +115,7 @@ namespace Perspex.Controls.UnitTests.Primitives
target.SelectedIndex = 1;
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
Assert.False(items[0].IsSelected);
Assert.True(items[1].IsSelected);
@ -241,6 +243,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
items.Add(new Item { IsSelected = true });
Assert.Equal(2, target.SelectedIndex);
@ -346,6 +349,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedItem = items[1];
Assert.False(items[0].IsSelected);
@ -376,6 +380,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedItem = items[1];
Assert.False(items[0].IsSelected);

4
tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests_Multiple.cs

@ -168,6 +168,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedItems.Add(items[0]);
target.SelectedItems.Add(items[1]);
@ -195,6 +196,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedItems = new PerspexList<object> { items[0], items[1] };
Assert.True(items[0].IsSelected);
@ -219,6 +221,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedItems.Add(items[0]);
target.SelectedItems.Add(items[1]);
target.SelectedItems.Remove(items[1]);
@ -270,6 +273,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
target.SelectedIndex = 1;
target.SelectedItems[0] = items[2];

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

@ -30,6 +30,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
var result = target.GetLogicalChildren()
.OfType<TabStripItem>()
@ -55,6 +56,7 @@ namespace Perspex.Controls.UnitTests.Primitives
};
target.ApplyTemplate();
target.Presenter.ApplyTemplate();
var result = target.GetLogicalChildren()
.OfType<TabStripItem>()

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

@ -160,42 +160,17 @@ namespace Perspex.Controls.UnitTests.Primitives
}
[Fact]
public void Nested_Templated_Controls_Have_Correct_TemplatedParent()
public void Nested_Templated_Control_Should_Not_Have_Template_Applied()
{
var target = new TestTemplatedControl
var target = new TemplatedControl
{
Template = new FuncControlTemplate(_ =>
{
return new ContentControl
{
Template = new FuncControlTemplate(parent =>
{
return new Border
{
Child = new ContentPresenter
{
[~ContentPresenter.ContentProperty] = parent.GetObservable(ContentControl.ContentProperty),
}
};
}),
Content = new TextBlock
{
}
};
}),
Template = new FuncControlTemplate(_ => new ScrollViewer())
};
target.ApplyTemplate();
var contentControl = target.GetTemplateChildren().OfType<ContentControl>().Single();
var border = contentControl.GetTemplateChildren().OfType<Border>().Single();
var presenter = contentControl.GetTemplateChildren().OfType<ContentPresenter>().Single();
var textBlock = (TextBlock)presenter.Content;
Assert.Equal(target, contentControl.TemplatedParent);
Assert.Equal(contentControl, border.TemplatedParent);
Assert.Equal(contentControl, presenter.TemplatedParent);
Assert.Equal(target, textBlock.TemplatedParent);
var child = (ScrollViewer)target.GetVisualChildren().Single();
Assert.Empty(child.GetVisualChildren());
}
[Fact]
@ -218,11 +193,11 @@ namespace Perspex.Controls.UnitTests.Primitives
return new StackPanel
{
Children = new Controls
{
new TextBlock
{
new TextBlock
{
}
}
}
};
}),
}
@ -236,6 +211,47 @@ namespace Perspex.Controls.UnitTests.Primitives
}
}
[Fact]
public void Nested_Templated_Controls_Have_Correct_TemplatedParent()
{
var target = new TestTemplatedControl
{
Template = new FuncControlTemplate(_ =>
{
return new ContentControl
{
Template = new FuncControlTemplate(parent =>
{
return new Border
{
Child = new ContentPresenter
{
[~ContentPresenter.ContentProperty] = parent.GetObservable(ContentControl.ContentProperty),
}
};
}),
Content = new TextBlock
{
}
};
}),
};
target.ApplyTemplate();
var contentControl = target.GetTemplateChildren().OfType<ContentControl>().Single();
contentControl.ApplyTemplate();
var border = contentControl.GetTemplateChildren().OfType<Border>().Single();
var presenter = contentControl.GetTemplateChildren().OfType<ContentPresenter>().Single();
var textBlock = (TextBlock)presenter.Content;
Assert.Equal(target, contentControl.TemplatedParent);
Assert.Equal(contentControl, border.TemplatedParent);
Assert.Equal(contentControl, presenter.TemplatedParent);
Assert.Equal(target, textBlock.TemplatedParent);
}
[Fact]
public void Nested_TemplatedControls_Should_Register_With_Correct_NameScope()
{
@ -245,19 +261,26 @@ namespace Perspex.Controls.UnitTests.Primitives
Content = "foo"
};
var root = new TestRoot { Child = target };
target.ApplyTemplate();
var border = target.GetVisualChildren().FirstOrDefault();
Assert.IsType<Border>(border);
var scrollViewer = border.GetVisualChildren().FirstOrDefault();
Assert.IsType<ScrollViewer>(scrollViewer);
((ScrollViewer)scrollViewer).ApplyTemplate();
var scrollContentPresenter = scrollViewer.GetVisualChildren().FirstOrDefault();
Assert.IsType<ScrollContentPresenter>(scrollContentPresenter);
((ContentPresenter)scrollContentPresenter).UpdateChild();
var contentPresenter = scrollContentPresenter.GetVisualChildren().FirstOrDefault();
Assert.IsType<ContentPresenter>(contentPresenter);
var borderNs = NameScope.GetNameScope((Control)border);
var scrollContentPresenterNs = NameScope.GetNameScope((Control)scrollContentPresenter);
Assert.NotNull(borderNs);
Assert.Same(scrollViewer, borderNs.Find("ScrollViewer"));
Assert.Same(contentPresenter, borderNs.Find("PART_ContentPresenter"));

24
tests/Perspex.Controls.UnitTests/ScrollViewerTests.cs

@ -1,12 +1,9 @@
// 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.Linq;
using Perspex.Controls;
using Perspex.Controls.Presenters;
using Perspex.Controls.Primitives;
using Perspex.Controls.Templates;
using Perspex.VisualTree;
using Xunit;
namespace Perspex.Controls.UnitTests
@ -23,28 +20,11 @@ namespace Perspex.Controls.UnitTests
};
target.ApplyTemplate();
target.Presenter.UpdateChild();
Assert.IsType<TextBlock>(target.Presenter.Child);
}
[Fact]
public void ScrollViewer_In_Template_Sets_Child_TemplatedParent()
{
var target = new ContentControl
{
Template = new FuncControlTemplate<ContentControl>(CreateNestedTemplate),
Content = "Foo",
};
target.ApplyTemplate();
var presenter = target.GetVisualDescendents()
.OfType<ContentPresenter>()
.Single(x => x.Name == "this");
Assert.Equal(target, presenter.TemplatedParent);
}
[Fact]
public void Offset_Should_Be_Coerced_To_Viewport()
{
@ -112,7 +92,7 @@ namespace Perspex.Controls.UnitTests
Template = new FuncControlTemplate<ScrollViewer>(CreateTemplate),
Content = new ContentPresenter
{
Name = "this"
Name = "PART_ContentPresenter",
}
};
}

17
tests/Perspex.Controls.UnitTests/TabControlTests.cs

@ -1,6 +1,7 @@
// 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 System.Collections.ObjectModel;
using System.Linq;
using Perspex.Controls.Presenters;
@ -181,8 +182,7 @@ namespace Perspex.Controls.UnitTests
Items = items,
};
target.ApplyTemplate();
ApplyTemplate(target);
var carousel = (Carousel)target.Pages;
var dataContext = ((TextBlock)carousel.Presenter.Panel.GetLogicalChildren().Single()).DataContext;
@ -229,7 +229,7 @@ namespace Perspex.Controls.UnitTests
Items = items,
};
target.ApplyTemplate();
ApplyTemplate(target);
var result = target.TabStrip.GetLogicalChildren()
.OfType<TabStripItem>()
@ -288,6 +288,17 @@ namespace Perspex.Controls.UnitTests
};
}
private void ApplyTemplate(TabControl target)
{
target.ApplyTemplate();
var carousel = (Carousel)target.Pages;
carousel.ApplyTemplate();
carousel.Presenter.ApplyTemplate();
var tabStrip = (TabStrip)target.TabStrip;
tabStrip.ApplyTemplate();
tabStrip.Presenter.ApplyTemplate();
}
private class Item
{
public Item(string value)

4
tests/Perspex.Controls.UnitTests/TopLevelTests.cs

@ -311,8 +311,9 @@ namespace Perspex.Controls.UnitTests
target.Template = CreateTemplate();
target.Content = child;
target.ApplyTemplate();
Assert.Throws<InvalidOperationException>(() => target.ApplyTemplate());
Assert.Throws<InvalidOperationException>(() => target.Presenter.ApplyTemplate());
}
}
@ -321,6 +322,7 @@ namespace Perspex.Controls.UnitTests
return new FuncControlTemplate<TestTopLevel>(x =>
new ContentPresenter
{
Name = "PART_ContentPresenter",
[!ContentPresenter.ContentProperty] = x[!ContentControl.ContentProperty],
});
}

10
tests/Perspex.Controls.UnitTests/TreeViewTests.cs

@ -24,7 +24,7 @@ namespace Perspex.Controls.UnitTests
DataTemplates = CreateNodeDataTemplate(),
};
target.ApplyTemplate();
ApplyTemplates(target);
Assert.Equal(new[] { "Root" }, ExtractItemHeader(target, 0));
Assert.Equal(new[] { "Child1", "Child2" }, ExtractItemHeader(target, 1));
@ -41,7 +41,7 @@ namespace Perspex.Controls.UnitTests
DataTemplates = CreateNodeDataTemplate(),
};
target.ApplyTemplate();
ApplyTemplates(target);
var container = (TreeViewItem)target.ItemContainerGenerator.Containers.Single().ContainerControl;
var header = (TextBlock)container.Header;
@ -116,7 +116,7 @@ namespace Perspex.Controls.UnitTests
Items = new[] { "Foo", "Bar", "Baz " },
};
target.ApplyTemplate();
ApplyTemplates(target);
var result = target.GetLogicalChildren()
.OfType<TreeViewItem>()
@ -172,7 +172,7 @@ namespace Perspex.Controls.UnitTests
Items = items,
};
target.ApplyTemplate();
ApplyTemplates(target);
var dataContexts = target.Presenter.Panel.Children
.Cast<Control>()
@ -187,6 +187,7 @@ namespace Perspex.Controls.UnitTests
private void ApplyTemplates(TreeView tree)
{
tree.ApplyTemplate();
tree.Presenter.ApplyTemplate();
ApplyTemplates(tree.Presenter.Panel.Children);
}
@ -196,6 +197,7 @@ namespace Perspex.Controls.UnitTests
{
control.Template = CreateTreeViewItemTemplate();
control.ApplyTemplate();
control.Presenter.ApplyTemplate();
ApplyTemplates(control.Presenter.Panel.Children);
}
}

10
tests/Perspex.Controls.UnitTests/Utils/HotKeyManagerTests.cs

@ -1,12 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
// 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 Moq;
using Perspex.Controls.Presenters;
using Perspex.Controls.Templates;
using Perspex.Controls.UnitTests.Primitives;
using Perspex.Input;
using Perspex.Platform;
using Perspex.Styling;
@ -35,6 +32,7 @@ namespace Perspex.Controls.UnitTests.Utils
tl.Content = button;
tl.Template = CreateWindowTemplate();
tl.ApplyTemplate();
tl.Presenter.ApplyTemplate();
HotKeyManager.SetHotKey(button, gesture1);

Loading…
Cancel
Save