// ----------------------------------------------------------------------- // // 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 ItemsControl : Control, IVisual { private static readonly ItemsPanelTemplate defaultPanel = new ItemsPanelTemplate(() => new StackPanel { Orientation = Orientation.Vertical }); public static readonly PerspexProperty ItemsProperty = PerspexProperty.Register("Items"); public static readonly PerspexProperty ItemsPanelProperty = PerspexProperty.Register("ItemsPanel", defaultValue: defaultPanel); private Panel panel; public ItemsControl() { 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.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)); } } }