通過繼承Collection<T>類型,並為其加入兩個事件ItemAdded和ItemRemoved,使用這兩個事件可以覺察到容器內項目的添加和刪除的操作。事件提供元素值和索引值的資料,使用起來如下:
static void Main(string[] args)
{
var list = new MyCollection<string>();
list.ItemAdded += list_ItemAdded;
list.ItemRemoved += list_ItemRemoved;
Console.WriteLine("list.Add(\"Mgen\");");
list.Add("Mgen");
Console.WriteLine("list.Add(\"Zhang\");");
list.Add("Zhang");
Console.WriteLine("list.Insert(0, \"Tony\");");
list.Insert(0, "Tony");
Console.WriteLine("list[2] = \"Chen\";");
list[2] = "Chen";
Console.WriteLine("list.Remove(\"Tony\");");
list.Remove("Tony");
Console.WriteLine("list.Clear();");
list.Clear();
}
static void list_ItemRemoved(object sender, CollectionItemEventArgs<string> e)
{
Console.WriteLine("移除 - 索引值 {0} 值 {1}", e.Index, e.Item);
}
static void list_ItemAdded(object sender, CollectionItemEventArgs<string> e)
{
Console.WriteLine("添加 - 索引值 {0} 值 {1}", e.Index, e.Item);
}
輸出:
list.Add("Mgen");
添加 - 索引值 0 值 Mgen
list.Add("Zhang");
添加 - 索引值 1 值 Zhang
list.Insert(0, "Tony");
添加 - 索引值 0 值 Tony
list[2] = "Chen";
移除 - 索引值 2 值 Zhang
添加 - 索引值 2 值 Chen
list.Remove("Tony");
移除 - 索引值 0 值 Tony
list.Clear();
移除 - 索引值 1 值 Chen
移除 - 索引值 0 值 Mgen
實現起來很簡單,通過改寫Collection<T>類型的:SetItem,InsertItem,RemoveItem和ClearItems方法,然後把相應添加或刪除操作調用相應事件就可以了。
完整代碼:
class CollectionItemEventArgs<T> : EventArgs
{
public int Index { get; private set; }
public T Item { get; private set; }
public CollectionItemEventArgs(int idx, T item)
{
Index = idx;
Item = item;
}
}
class MyCollection<T> : Collection<T>
{
public event EventHandler<CollectionItemEventArgs<T>> ItemAdded;
protected virtual void OnItemAdded(CollectionItemEventArgs<T> e)
{
var handler = this.ItemAdded;
if (handler != null)
handler(this, e);
}
public event EventHandler<CollectionItemEventArgs<T>> ItemRemoved;
protected virtual void OnItemRemoved(CollectionItemEventArgs<T> e)
{
var handler = this.ItemRemoved;
if (handler != null)
handler(this, e);
}
protected override void ClearItems()
{
for (int i = Count - 1; i >= 0; i--)
{
OnItemRemoved(new CollectionItemEventArgs<T>(i, this[i]));
}
base.ClearItems();
}
protected override void RemoveItem(int index)
{
OnItemRemoved(new CollectionItemEventArgs<T>(index, this[index]));
base.RemoveItem(index);
}
protected override void InsertItem(int index, T item)
{
OnItemAdded(new CollectionItemEventArgs<T>(index, item));
base.InsertItem(index, item);
}
protected override void SetItem(int index, T item)
{
OnItemRemoved(new CollectionItemEventArgs<T>(index, this[index]));
OnItemAdded(new CollectionItemEventArgs<T>(index, item));
base.SetItem(index, item);
}
}