using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.ComponentModel; using System.Linq; using System.Text; using RainmeterStudio.Core.Model; using RainmeterStudio.Core.Utils; namespace RainmeterStudio.UI.ViewModel { /// /// Contains the view model of a reference /// public class ReferenceViewModel : INotifyPropertyChanged, INotifyCollectionChanged { private ObservableCollection _children = new ObservableCollection(); #region Properties /// /// Gets the linked reference /// public Reference Reference { get; private set; } /// /// Gets or sets the name /// public string Name { get { return Reference.Name; } } /// /// Gets an enumerable of this object's children /// public ObservableCollection Children { get { return _children; } } private bool _isExpanded = true; /// /// Gets or sets a property indicating if the tree view item is expanded /// public bool IsExpanded { get { return _isExpanded; } set { _isExpanded = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsExpanded")); } } private bool _isSelected; /// /// Gets or sets a property indicating if the tree view item is selected /// public bool IsSelected { get { return _isSelected; } set { _isSelected = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("IsSelected")); } } #endregion #region Events /// /// Event triggered when a property is changed /// public event PropertyChangedEventHandler PropertyChanged; #endregion #region Constructor /// /// Creates a new instance of reference view model /// /// Reference public ReferenceViewModel(Reference reference) { Reference = reference; Reference.CollectionChanged += Reference_CollectionChanged; Reference.PropertyChanged += Reference_PropertyChanged; RefreshChildren(); } private void Reference_PropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == "Name" && PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Name")); } private void Reference_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { List newItems = new List(); List oldItems = new List(); // Update collection switch (e.Action) { case NotifyCollectionChangedAction.Add: newItems = e.NewItems.Cast().Select(x => new ReferenceViewModel(x)).ToList(); break; case NotifyCollectionChangedAction.Remove: oldItems = _children.Where(x => e.OldItems.Contains(x.Reference)).ToList(); break; case NotifyCollectionChangedAction.Replace: newItems = e.NewItems.Cast().Select(x => new ReferenceViewModel(x)).ToList(); oldItems = _children.Where(x => e.OldItems.Contains(x.Reference)).ToList(); break; default: RefreshChildren(); break; } oldItems.ForEach(x => _children.Remove(x)); newItems.ForEach(_children.Add); // Pass event if (CollectionChanged != null) CollectionChanged(this, new NotifyCollectionChangedEventArgs(e.Action, newItems, oldItems)); } #endregion #region Operations /// /// Sets the 'IsExpanded' property for the entire subtree /// /// Value to set public void TreeExpand(bool value) { IsExpanded = value; } private void RefreshChildren() { _children.Clear(); Reference.Children.Select(x => new ReferenceViewModel(x)).ForEach(_children.Add); } #endregion /// /// Triggered when the linked reference collection changes /// public event NotifyCollectionChangedEventHandler CollectionChanged; } }