繁体   English   中英

静态ObservableCollection事件未触发

[英]Static ObservableCollection Event is not firing

我有以下使用linq更新的static ObservableCollection 为什么事件没有解雇?

public static class myViewModel
{

    private static ObservableCollection<ObjA> CollectionA = new ObservableCollection<ObjA>();
    private static ObservableCollection<ObjB> CollectionB = new ObservableCollection<ObjB>();

    static myViewModel()
    {
        CollectionA.CollectionChanged += new NotifyCollectionChangedEventHandler(myHandler);
        CollectionA = new ObservableCollection(CollectionB.Select(abc=> new ObjA(abc, True));
    }

    private static void myHandler(object sender, NotifyCollectionChangedEventArgs e)
    {  
        //To do
        throw new NotImplementedException();
    }

    private static void updateCollection()
    {

        foreach (var x in CollectionA)
        {
            CollectionA.field=5;
        }
    }
}

第一步:为CollectionA一个事件处理程序。

CollectionA.CollectionChanged += new NotifyCollectionChangedEventHandler(myHandler);

第二步: 丢弃 CollectionA并将其替换为没有处理程序的不同集合。

CollectionA = new ObservableCollection(CollectionB.Select(abc=> new ObjA(abc, true));

看看你在那里做了什么?

CollectionA返回对集合对象的引用。 您没有向该集合对象添加项目。 您正在使用其他集合对象替换该集合对象。

而是将项目添加到现有集合中:

CollectionA.CollectionChanged += new NotifyCollectionChangedEventHandler(myHandler);

foreach (var x in CollectionB.Select(abc=> new ObjA(abc, true)))
{
    CollectionA.Add(x);
}

如果您确实想要一次性替换集合,则需要将处理程序添加到集合中:

CollectionA = new ObservableCollection(CollectionB.Select(abc=> new ObjA(abc, true));

CollectionA.CollectionChanged += myHandler;

如果myHandler具有正确的参数和返回类型,则不需要new NotifyCollectionChangedEventHandler

处理这类事情的常用方法是使CollectionA成为一个添加处理程序本身的属性:

private static ObservableCollection<ObjA> _collectionA;
public static ObservableCollection<ObjA> CollectionA {
    get { return _collectionA; }
    set {
        if (_collectionA != value)
        {
            //  Remove handler from old collection, if any
            if (_collectionA != null)
            {
                _collectionA.CollectionChanged -= myHandler;
            }

            _collectionA = value;

            if (_collectionA != null)
            {
                _collectionA.CollectionChanged += myHandler;

                //  Whatever myHandler does on new items, you probably want to do 
                //  that here for each item in the new collection. 
            }
        }
    }
}

static myViewModel()
{
    //  Now, whenever you replace CollectionA, the setter will add the changed 
    //  handler automatically and you don't have to think about it. 
    CollectionA = new ObservableCollection(CollectionB.Select(abc=> new(abc, True));
}

更新

现在,什么我们与项目在做什么? 也许我们想知道它们的属性何时发生变化。 ObservableCollection不会为我们这样做,但我们可以自己连接它。

考虑以更方便可重用的方式重构此代码的方法很有趣。

private static ObservableCollection<ObjA> _collectionA;
public static ObservableCollection<ObjA> CollectionA
{
    get { return _collectionA; }
    set
    {
        if (_collectionA != value)
        {
            //  Remove handler from old collection, if any
            if (_collectionA != null)
            {
                _collectionA.CollectionChanged -= myHandler;
            }

            //  1. Remove property changed handlers from old collection items (if old collection not null) 
            //  2. Add property changed to new collection items (if new collection not null) 
            AddAndRemovePropertyChangedHandlers(_collectionA, value, ObjA_PropertyChanged);

            _collectionA = value;

            if (_collectionA != null)
            {
                _collectionA.CollectionChanged += myHandler;
            }
        }
    }
}

//  NotifyCollectionChangedEventArgs gives us non-generic IList rather than IEnumerable
//  but all we're doing is foreach, so make it as general as possible. 
protected static void AddAndRemovePropertyChangedHandlers(
    System.Collections.IEnumerable oldItems, 
    System.Collections.IEnumerable newItems, 
    PropertyChangedEventHandler handler)
{
    if (oldItems != null)
    {
        //  Some items may not implement INotifyPropertyChanged. 
        foreach (INotifyPropertyChanged oldItem in oldItems.Cast<Object>()
            .Where(item => item is INotifyPropertyChanged))
        {
            oldItem.PropertyChanged -= handler;
        }
    }

    if (newItems != null)
    {
        foreach (INotifyPropertyChanged newItem in newItems.Cast<Object>()
            .Where(item => item is INotifyPropertyChanged))
        {
            newItem.PropertyChanged += handler;
        }
    }
}

private static void ObjA_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
}

private static void myHandler(object sender, 
    System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    //  If e.Action is Reset, you don't get the items that were removed. Oh well. 
    AddAndRemovePropertyChangedHandlers(e.OldItems, e.NewItems, ObjA_PropertyChanged);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM