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;
}
}