我们在进行集合处理时,有时希望能够监视集合的变化,并在满足一定条件时触发处理事件。.net框架下似乎(没见到)没有这样的支持,因此有必要我们自己对Collection进行扩展,以下这个简单的C#控制台应用程序便给出一个简单的方案。
1. 核心实现部分代码
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace CollectionWithEvent
{
public enum CollectionOperation
{
Insert,
Remove,
Set
}
public class CollectionEventArgs<U> : EventArgs
{
public CollectionOperation Operation { get; private set; }
public int Index { get; private set; }
public U Item { get; private set; }
public CollectionEventArgs(U item, CollectionOperation operation, int index)
{
Item = item;
Index = index;
Operation = operation;
}
}
public class CollectionWithEvents<T> : Collection<T>
{
public event EventHandler<CollectionEventArgs<T>> CollectionChanged;
public CollectionWithEvents()
{
}
public CollectionWithEvents(IEnumerable<T> items)
: base(items.ToList())
{
}
protected override void InsertItem(int index, T item)
{
base.InsertItem(index, item);
OnCollectionChanged(item, CollectionOperation.Insert, index);
}
protected override void RemoveItem(int index)
{
base.RemoveItem(index);
OnCollectionChanged(default(T), CollectionOperation.Remove, index);
}
protected override void SetItem(int index, T item)
{
base.SetItem(index, item);
OnCollectionChanged(item, CollectionOperation.Set, index);
}
private void OnCollectionChanged(T item, CollectionOperation operation, int index)
{
if(CollectionChanged != null)
CollectionChanged(this,new CollectionEventArgs<T>(item,operation,index));
}
public void AddRange(IEnumerable<T> items)
{
foreach(var item in items)
Add(item);
}
}
}
2. 测试对象类定义
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CollectionWithEvent
{
public class StringObj
{
private string _val;
public string Val
{
get
{
return _val ?? "";
}
}
public StringObj(string val)
{
_val = val;
}
}
}
3. 测试主程序
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CollectionWithEvent
{
class Program
{
static void Main(string[] args)
{
CollectionWithEvents<StringObj> col = new CollectionWithEvents<StringObj>();
col.CollectionChanged += new EventHandler<CollectionEventArgs<StringObj>>(EventChanged);
col.Insert(0, new StringObj("ni"));
col.Insert(1, new StringObj("hao"));
col.Add(new StringObj("ya"));
col.Add(new StringObj("!"));
col.RemoveAt(3);
col[2] = new StringObj("ma");
Console.ReadKey();
}
private static void EventChanged(object sender, CollectionEventArgs<StringObj> e)
{
string msg = string.Empty;
msg = e.Operation.ToString();
msg += " ";
msg += e.Index.ToString();
msg += " ";
if (e.Item != null)
msg += e.Item.Val;
Console.WriteLine(msg);
}
}
}
当进行集合操作时会触发绑定的事件,这里的运行结果如下: