diff --git a/Perspex.Controls/Generators/ItemContainerGenerator.cs b/Perspex.Controls/Generators/ItemContainerGenerator.cs index e9c6f68431..bdcfd665b7 100644 --- a/Perspex.Controls/Generators/ItemContainerGenerator.cs +++ b/Perspex.Controls/Generators/ItemContainerGenerator.cs @@ -20,7 +20,7 @@ namespace Perspex.Controls.Generators private ItemContainerGeneratorState state; - public ItemContainerGenerator(ItemsControl owner) + public ItemContainerGenerator(Control owner) { this.Owner = owner; } @@ -48,7 +48,7 @@ namespace Perspex.Controls.Generators } } - protected ItemsControl Owner + protected Control Owner { get; private set; diff --git a/Perspex.Controls/Presenters/ItemsPresenter.cs b/Perspex.Controls/Presenters/ItemsPresenter.cs index 51652a0ed7..0b2b2bdd85 100644 --- a/Perspex.Controls/Presenters/ItemsPresenter.cs +++ b/Perspex.Controls/Presenters/ItemsPresenter.cs @@ -29,6 +29,12 @@ namespace Perspex.Controls.Presenters this.GetObservableWithHistory(ItemsProperty).Subscribe(this.ItemsChanged); } + public ItemContainerGenerator ItemContainerGenerator + { + get; + private set; + } + public IEnumerable Items { get { return this.GetValue(ItemsProperty); } @@ -81,14 +87,13 @@ namespace Perspex.Controls.Presenters private IItemContainerGenerator GetGenerator() { - ItemsControl i = this.TemplatedParent as ItemsControl; - - if (i == null) + if (this.ItemContainerGenerator == null) { - throw new InvalidOperationException("ItemsPresenter must be part of an ItemsControl template."); + ItemsControl i = this.TemplatedParent as ItemsControl; + this.ItemContainerGenerator = i?.ItemContainerGenerator ?? new ItemContainerGenerator(this); } - return i.ItemContainerGenerator; + return this.ItemContainerGenerator; } private void ItemsChanged(Tuple value) diff --git a/Tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj b/Tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj index 788271cece..59f39b1a5c 100644 --- a/Tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj +++ b/Tests/Perspex.Controls.UnitTests/Perspex.Controls.UnitTests.csproj @@ -90,6 +90,7 @@ + diff --git a/Tests/Perspex.Controls.UnitTests/Presenters/ItemsPresenterTests.cs b/Tests/Perspex.Controls.UnitTests/Presenters/ItemsPresenterTests.cs new file mode 100644 index 0000000000..1e91b8b6e3 --- /dev/null +++ b/Tests/Perspex.Controls.UnitTests/Presenters/ItemsPresenterTests.cs @@ -0,0 +1,77 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2015 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Controls.UnitTests.Presenters +{ + using Perspex.Controls.Presenters; + using Perspex.Input; + using Perspex.VisualTree; + using System.Linq; + using Xunit; + + public class ItemsPresenterTests + { + [Fact] + public void Panel_Should_Be_Created_From_ItemsPanel_Template() + { + var panel = new Panel(); + var target = new ItemsPresenter + { + ItemsPanel = new ItemsPanelTemplate(() => panel), + }; + + target.ApplyTemplate(); + + Assert.Equal(panel, target.Panel); + } + + [Fact] + public void Panel_TemplatedParent_Should_Be_Set() + { + var target = new ItemsPresenter(); + + target.ApplyTemplate(); + + Assert.Equal(target, target.Panel.TemplatedParent); + } + + [Fact] + public void Panel_TabNavigation_Should_Be_Set_To_Once() + { + var target = new ItemsPresenter(); + + target.ApplyTemplate(); + + Assert.Equal(KeyboardNavigationMode.Once, KeyboardNavigation.GetTabNavigation(target.Panel)); + } + + [Fact] + public void Panel_Should_Be_Visual_Child() + { + var target = new ItemsPresenter(); + + target.ApplyTemplate(); + + var child = target.GetVisualChildren().Single(); + + Assert.Equal(target.Panel, child); + } + + [Fact] + public void Items_Should_Be_Created_On_ApplyTemplate() + { + var target = new ItemsPresenter + { + Items = new[] { "foo", "bar" }, + }; + + target.ApplyTemplate(); + + Assert.Equal(2, target.Panel.GetVisualChildren().Count()); + } + } +} +