using System.Collections.ObjectModel; using System.ComponentModel; namespace Egametang { /// /// Base class for all ViewModel classes displayed by TreeViewItems. /// This acts as an adapter between a raw data object and a TreeViewItem. /// public class TreeViewItemViewModel : INotifyPropertyChanged { #region Data static readonly TreeViewItemViewModel dummyChild = new TreeViewItemViewModel(); readonly ObservableCollection children; readonly TreeViewItemViewModel parent; bool isExpanded; bool isSelected; #endregion // Data #region Constructors protected TreeViewItemViewModel(TreeViewItemViewModel parent, bool lazyLoadChildren) { this.parent = parent; children = new ObservableCollection(); if (lazyLoadChildren) { children.Add(dummyChild); } } // This is used to create the DummyChild instance. private TreeViewItemViewModel() { } #endregion // Constructors #region Children /// /// Returns the logical child items of this object. /// public ObservableCollection Children { get { return children; } } #endregion // Children #region HasLoadedChildren /// /// Returns true if this object's Children have not yet been populated. /// public bool HasDummyChild { get { return this.Children.Count == 1 && this.Children[0] == dummyChild; } } #endregion // HasLoadedChildren #region IsExpanded /// /// Gets/sets whether the TreeViewItem /// associated with this object is expanded. /// public bool IsExpanded { get { return isExpanded; } set { if (value != isExpanded) { isExpanded = value; this.OnPropertyChanged("IsExpanded"); } // Expand all the way up to the root. if (isExpanded && parent != null) { parent.IsExpanded = true; } // Lazy load the child items, if necessary. if (this.HasDummyChild) { this.Children.Remove(dummyChild); this.LoadChildren(); } } } #endregion // IsExpanded #region IsSelected /// /// Gets/sets whether the TreeViewItem /// associated with this object is selected. /// public bool IsSelected { get { return isSelected; } set { if (value != isSelected) { isSelected = value; this.OnPropertyChanged("IsSelected"); } } } #endregion // IsSelected #region LoadChildren /// /// Invoked when the child items need to be loaded on demand. /// Subclasses can override this to populate the Children collection. /// protected virtual void LoadChildren() { } #endregion // LoadChildren #region Parent public TreeViewItemViewModel Parent { get { return parent; } } #endregion // Parent #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged(string propertyName) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion // INotifyPropertyChanged Members } }