如何在collection元素对象触发事件时触发事件

时间:2010-09-28 22:01:28

标签: c#

我有一个observableCollection并在MyObject中连接了一个事件,是否有一种cunnign方法可以在集合中获取该事件而无需重新编写集合类?

    public class MyObjectCollection : ObservableCollection<MyObject>
    {
        public MyObjectCollection()
        {
            //some cunning code here
        }
    }

我怀疑我必须重写ObservableCollection类,但不幸的是没有接口(比如有一个IDictionary)

2 个答案:

答案 0 :(得分:2)

赞成合成而不是继承。而不是扩展ObservableCollection,实现您需要的接口(可能是INotifyCollectionChanged和IList)并将ObservableCollection保存为私有字段。这样,您可以连接自己的添加和删除调用,并使用添加到集合中的对象执行您想要的操作。

答案 1 :(得分:1)

再次阅读本文,我认为你是在追求这样的事情:

public sealed class CollectionEventMonitor<TItem, TEventArgs> : IDisposable
    where TEventArgs: EventArgs
{
    private readonly INotifyCollectionChanged _collection;
    private readonly Action<TItem, EventHandler<TEventArgs>> _addEvent;
    private readonly Action<TItem, EventHandler<TEventArgs>> _removeEvent;

    public event EventHandler<TEventArgs> ItemFiredEvent;

    public CollectionEventMonitor(INotifyCollectionChanged collection, 
        Action<TItem, EventHandler<TEventArgs>> addEvent, 
        Action<TItem, EventHandler<TEventArgs>> removeEvent)
    {
        _addEvent = addEvent;
        _removeEvent = removeEvent;
        _collection = collection;
        _collection.CollectionChanged += _collection_CollectionChanged;
    }

    void _collection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        switch (e.Action)
        {
            case NotifyCollectionChangedAction.Add:
                foreach (var item in e.NewItems.Cast<TItem>())
                    _addEvent(item, OnItemFiredEvent);
                break;
            case NotifyCollectionChangedAction.Remove:
                foreach (var item in e.OldItems.Cast<TItem>())
                    _removeEvent(item, OnItemFiredEvent);
                break;
            case NotifyCollectionChangedAction.Replace:
                foreach (var item in e.OldItems.Cast<TItem>())
                    _removeEvent(item, OnItemFiredEvent);
                foreach (var item in e.NewItems.Cast<TItem>())
                    _addEvent(item, OnItemFiredEvent);
                break;
            case NotifyCollectionChangedAction.Move:
                break;
            case NotifyCollectionChangedAction.Reset:
                foreach (var item in e.OldItems.Cast<TItem>())
                    _removeEvent(item, OnItemFiredEvent);
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }
    }

    private void OnItemFiredEvent(Object item, TEventArgs eventArgs)
    {
        var handler = ItemFiredEvent;
        if (handler != null)
            handler(item, eventArgs);
    }

    public void Dispose()
    {
        _collection.CollectionChanged -= _collection_CollectionChanged;
    }
}

这是粗略的,未经测试的,但它应该给你基本的想法。你这样使用它:

        var collection = new ObservableCollection<Foo>();
        var monitor = 
            new CollectionEventMonitor<Foo, EventArgs>(collection,
                (foo,handler) => foo.Bar += handler,
                (foo,handler) => foo.Bar -= handler);

此方法的优点是您可以监视项目事件的任何可观察集合,而不是创建特殊的包装器集合。您还可以为同一个集合创建多个监视器实例,允许不同的上下文监视同一集合中项目的不同事件。