// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex.Controls { using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; public class ItemsControl : TemplatedControl { 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 Dictionary controlsByItem = new Dictionary(); private Dictionary itemsByControl = new Dictionary(); public ItemsControl() { this.GetObservableWithHistory(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); } } public Control GetControlForItem(object item) { Control result; this.controlsByItem.TryGetValue(item, out result); return result; } public object GetItemForControl(Control control) { object result; this.itemsByControl.TryGetValue(control, out result); return result; } public IEnumerable GetAllItemControls() { return this.controlsByItem.Values; } internal Control CreateItemControl(object item) { Control control = this.CreateItemControlOverride(item); this.itemsByControl.Add(control, item); this.controlsByItem.Add(item, control); return control; } internal void RemoveItemControls(IEnumerable items) { foreach (object i in items) { Control control = this.GetControlForItem(i); this.controlsByItem.Remove(i); this.itemsByControl.Remove(control); } } internal void ClearItemControls() { this.controlsByItem.Clear(); this.itemsByControl.Clear(); } protected virtual Control CreateItemControlOverride(object item) { return (item as Control) ?? this.GetDataTemplate(item).Build(item); } private void ItemsChanged(Tuple value) { INotifyPropertyChanged inpc = value.Item1 as INotifyPropertyChanged; if (inpc != null) { inpc.PropertyChanged -= ItemsPropertyChanged; } if (value.Item2 == null || !value.Item2.OfType().Any()) { this.Classes.Add(":empty"); } else { this.Classes.Remove(":empty"); } inpc = value.Item2 as INotifyPropertyChanged; if (inpc != null) { inpc.PropertyChanged += ItemsPropertyChanged; } } private void ItemsPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Count") { if (((IList)sender).Count == 0) { this.Classes.Add(":empty"); } else { this.Classes.Remove(":empty"); } } } } }