diff --git a/Perspex/Controls/ControlTemplate.cs b/Perspex/Controls/ControlTemplate.cs index 393c3138ae..c54833cd35 100644 --- a/Perspex/Controls/ControlTemplate.cs +++ b/Perspex/Controls/ControlTemplate.cs @@ -7,8 +7,6 @@ namespace Perspex.Controls { using System; - using System.Linq; - using Perspex.Controls; public class ControlTemplate { diff --git a/Perspex/Controls/DataTemplate.cs b/Perspex/Controls/DataTemplate.cs index 44e9335276..1a3cb139a7 100644 --- a/Perspex/Controls/DataTemplate.cs +++ b/Perspex/Controls/DataTemplate.cs @@ -12,7 +12,7 @@ namespace Perspex.Controls public class DataTemplate { public static readonly DataTemplate Default = - new DataTemplate(typeof(object), o => new TextBox { Text = o.ToString() }); + new DataTemplate(typeof(object), o => new TextBlock { Text = o.ToString() }); public DataTemplate(Type type, Func build) : this(o => type.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()), build) diff --git a/Perspex/Controls/ItemsControl.cs b/Perspex/Controls/ItemsControl.cs index b574a5e296..a9b9dcad6b 100644 --- a/Perspex/Controls/ItemsControl.cs +++ b/Perspex/Controls/ItemsControl.cs @@ -6,13 +6,9 @@ namespace Perspex.Controls { - using System; using System.Collections; - using System.Collections.Generic; - using System.Linq; - using Perspex.Layout; - public class ItemsControl : Control, IVisual + public class ItemsControl : TemplatedControl { private static readonly ItemsPanelTemplate defaultPanel = new ItemsPanelTemplate(() => new StackPanel { Orientation = Orientation.Vertical }); @@ -23,11 +19,8 @@ namespace Perspex.Controls public static readonly PerspexProperty ItemsPanelProperty = PerspexProperty.Register("ItemsPanel", defaultValue: defaultPanel); - private Panel panel; - public ItemsControl() { - this.GetObservable(ItemsProperty).Subscribe(this.ItemsChanged); } public IEnumerable Items @@ -41,59 +34,5 @@ namespace Perspex.Controls get { return this.GetValue(ItemsPanelProperty); } set { this.SetValue(ItemsPanelProperty, value); } } - - IEnumerable IVisual.ExistingVisualChildren - { - get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); } - } - - IEnumerable IVisual.VisualChildren - { - get { return Enumerable.Repeat(this.GetPanel(), 1); } - } - - protected override Size MeasureOverride(Size availableSize) - { - Panel panel = this.GetPanel(); - panel.Measure(availableSize); - return panel.DesiredSize.Value; - } - - protected override Size ArrangeOverride(Size finalSize) - { - this.GetPanel().Arrange(new Rect(finalSize)); - return finalSize; - } - - private IEnumerable CreateItems(IEnumerable items) - { - if (items != null) - { - return items - .Cast() - .Select(x => this.GetDataTemplate(x).Build(x)) - .OfType(); - } - else - { - return Enumerable.Empty(); - } - } - - private Panel GetPanel() - { - if (this.panel == null) - { - this.panel = this.ItemsPanel.Build(); - this.panel.Children = new PerspexList(this.CreateItems(this.Items)); - } - - return this.panel; - } - - private void ItemsChanged(IEnumerable items) - { - this.GetPanel().Children = new PerspexList(this.CreateItems(items)); - } } } diff --git a/Perspex/Controls/ItemsPresenter.cs b/Perspex/Controls/ItemsPresenter.cs new file mode 100644 index 0000000000..0a1e40fd1e --- /dev/null +++ b/Perspex/Controls/ItemsPresenter.cs @@ -0,0 +1,99 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2014 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Controls +{ + using System; + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using Perspex.Layout; + + public class ItemsPresenter : Control, IVisual + { + public static readonly PerspexProperty ItemsProperty = + PerspexProperty.Register("Items"); + + public static readonly PerspexProperty ItemsPanelProperty = + PerspexProperty.Register("ItemsPanel"); + + private Panel panel; + + public ItemsPresenter() + { + this.GetObservable(ItemsProperty).Subscribe(this.ItemsChanged); + } + + public IEnumerable Items + { + get { return this.GetValue(ItemsProperty); } + set { this.SetValue(ItemsProperty, value); } + } + + public ItemsPanelTemplate ItemsPanel + { + get { return this.GetValue(ItemsPanelProperty); } + set { this.SetValue(ItemsPanelProperty, value); } + } + + IEnumerable IVisual.ExistingVisualChildren + { + get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); } + } + + IEnumerable IVisual.VisualChildren + { + get { return Enumerable.Repeat(this.GetPanel(), 1); } + } + + protected override Size MeasureOverride(Size availableSize) + { + Panel panel = this.GetPanel(); + panel.Measure(availableSize); + return panel.DesiredSize.Value; + } + + protected override Size ArrangeOverride(Size finalSize) + { + this.GetPanel().Arrange(new Rect(finalSize)); + return finalSize; + } + + private IEnumerable CreateItems(IEnumerable items) + { + if (items != null) + { + return items + .Cast() + .Select(x => this.GetDataTemplate(x).Build(x)) + .OfType(); + } + else + { + return Enumerable.Empty(); + } + } + + private Panel GetPanel() + { + if (this.panel == null && this.ItemsPanel != null) + { + this.panel = this.ItemsPanel.Build(); + this.ItemsChanged(this.Items); + } + + return this.panel; + } + + private void ItemsChanged(IEnumerable items) + { + if (this.panel != null) + { + this.panel.Children = new PerspexList(this.CreateItems(items)); + } + } + } +} diff --git a/Perspex/Perspex.csproj b/Perspex/Perspex.csproj index 90face9694..0aca902794 100644 --- a/Perspex/Perspex.csproj +++ b/Perspex/Perspex.csproj @@ -70,6 +70,7 @@ + @@ -126,6 +127,7 @@ + diff --git a/Perspex/Themes/Default/DefaultTheme.cs b/Perspex/Themes/Default/DefaultTheme.cs index 12452031f9..94431c0c0d 100644 --- a/Perspex/Themes/Default/DefaultTheme.cs +++ b/Perspex/Themes/Default/DefaultTheme.cs @@ -15,7 +15,9 @@ namespace Perspex.Themes.Default this.Add(new ButtonStyle()); this.Add(new CheckBoxStyle()); this.Add(new ContentControlStyle()); + this.Add(new ItemsControlStyle()); this.Add(new TextBoxStyle()); + this.Add(new ItemsControlStyle()); } } } diff --git a/Perspex/Themes/Default/ItemsControlStyle.cs b/Perspex/Themes/Default/ItemsControlStyle.cs new file mode 100644 index 0000000000..06172a3595 --- /dev/null +++ b/Perspex/Themes/Default/ItemsControlStyle.cs @@ -0,0 +1,41 @@ +// ----------------------------------------------------------------------- +// +// Copyright 2014 MIT Licence. See licence.md for more information. +// +// ----------------------------------------------------------------------- + +namespace Perspex.Themes.Default +{ + using System; + using System.Linq; + using Perspex.Controls; + using Perspex.Media; + using Perspex.Shapes; + using Perspex.Styling; + + public class ItemsControlStyle : Styles + { + public ItemsControlStyle() + { + this.AddRange(new[] + { + new Style(x => x.OfType()) + { + Setters = new[] + { + new Setter(Button.TemplateProperty, ControlTemplate.Create(this.Template)), + }, + }, + }); + } + + private Control Template(ItemsControl control) + { + return new ItemsPresenter + { + [~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty], + [~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty], + }; + } + } +}