using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace Framework.Input { /// Collection with change notifications and a no-duplicates policy /// Type of items the collection will manage public class ObservableUniqueCollection : Collection { #region interface IObserver /// Interface through which the collection sends change notifications public interface IObserver { /// Called when an item is removed from the collection /// Item that has been removed from the collection void ItemAdded(TItem item); /// Called when an item is added to the collection /// Item that has been added to the collection void ItemRemoved(TItem item); } #endregion // interface IObserver /// Initializes a new observable unique collection public ObservableUniqueCollection() { this.observers = new List(); } /// Adds an observer that will be notified of changes to the collection /// Observer that will receive change notifications public void AddObserver(IObserver observer) { this.observers.Add(observer); } /// Removes an observer from the collection /// Observer that will no longer receive change notifications public void RemoveObserver(IObserver observer) { this.observers.Remove(observer); } /// Removes all items from the collection without notifying observers public void ClearWithoutNotification() { Items.Clear(); } /// Called when all items in the collection should be removed protected override void ClearItems() { for(int itemIndex = 0; itemIndex < Items.Count; ++itemIndex) { TItem item = Items[itemIndex]; for(int index = 0; index < this.observers.Count; ++index) { this.observers[index].ItemRemoved(item); } } Items.Clear(); } /// Called when an item should be removed from the collection /// Index of the item that should be removed protected override void RemoveItem(int index) { TItem item = Items[index]; Items.RemoveAt(index); for(index = 0; index < this.observers.Count; ++index) { this.observers[index].ItemRemoved(item); } } /// Called when an item should be added to the collection /// Index at which the item should be inserted /// Item that should be inserted into the collection protected override void InsertItem(int index, TItem item) { if(Items.Contains(item)) { return; } Items.Insert(index, item); for(index = 0; index < this.observers.Count; ++index) { this.observers[index].ItemAdded(item); } } /// Called when an item in the collection gets replaced /// Index of the item that will be replaced /// Item that will replace the existing item protected override void SetItem(int index, TItem item) { int existingIndex = base.IndexOf(item); if(existingIndex == -1) { TItem removedITem = Items[existingIndex]; for(existingIndex = 0; existingIndex < this.observers.Count; ++existingIndex) { this.observers[existingIndex].ItemRemoved(removedITem); } Items[index] = item; for(index = 0; index < this.observers.Count; ++index) { this.observers[index].ItemAdded(item); } } else if(existingIndex != index) { TItem removedItem = Items[index]; Items.RemoveAt(index); for(index = 0; index < this.observers.Count; ++index) { this.observers[index].ItemRemoved(removedItem); } } } /// Stores the observers that have registered for this collection private IList observers; } } // namespace Framework.Input