C#中ObservableCollection的CollectionChanged事件

4
如何优化这段代码:
void CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    if (sender is ObservableCollection<PromotionPurchaseAmount>)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (PromotionPurchaseAmount item in e.NewItems)
            {
                //Removed items
                item.PropertyChanged -= EntityViewModelPropertyChanged;
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (PromotionPurchaseAmount item in e.NewItems)
            {
                //Added items
                item.PropertyChanged += EntityViewModelPropertyChanged;
            }
        }
    }
    else if (sender is ObservableCollection<PromotionItemPricing>)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (PromotionItemPricing item in e.NewItems)
            {
                //Removed items
                item.PropertyChanged -= EntityViewModelPropertyChanged;
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (PromotionItemPricing item in e.NewItems)
            {
                //Added items
                item.PropertyChanged += EntityViewModelPropertyChanged;
            }
        }
    }
    else if (sender is ObservableCollection<PromotionItem>)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            foreach (PromotionItem item in e.NewItems)
            {
                //Removed items
                item.PropertyChanged -= EntityViewModelPropertyChanged;
            }
        }
        else if (e.Action == NotifyCollectionChangedAction.Add)
        {
            foreach (PromotionItem item in e.NewItems)
            {
                //Added items
                item.PropertyChanged += EntityViewModelPropertyChanged;
            }
        }
    }
}

你具体在寻找什么?代码是否无法正常工作?也许将其发布到http://codereview.stackexchange.com会更合适。 - Dan J
1
帮了我,不确定为什么被关闭了。 - Todd Main
2
帮了我很多,我不认为它太局限了。 - Eric
1个回答

6
  1. When e.Action == NotifyCollectionChangedAction.Remove you need to iterate over e.OldItems instead of e.NewItems.
  2. When e.Action == NotifyCollectionChangedAction.Replace you need to iterate over e.OldItems to remove the event handler from the old items and you need to iterate over e.NewItems to add the event handler to the new items.
  3. Refactor the code like this:

    if (sender is ObservableCollection<PromotionPurchaseAmount> || 
        sender is ObservableCollection<PromotionItemPricing> || 
        sender is ObservableCollection<PromotionItem>)
    {
        if (e.Action == NotifyCollectionChangedAction.Remove ||
            e.Action == NotifyCollectionChangedAction.Replace)
        {
    
            foreach (INotifyPropertyChanged item in e.OldItems)
            {
                //Removed items
                item.PropertyChanged -= EntityViewModelPropertyChanged;
            }
        }
        if (e.Action == NotifyCollectionChangedAction.Add ||
            e.Action == NotifyCollectionChangedAction.Replace)
        {
            foreach (INotifyPropertyChanged item in e.NewItems)
            {
                //Added items
                item.PropertyChanged += EntityViewModelPropertyChanged;
            }
        }
    }
    
这是可行的,因为您所有的促销类都实现了INotifyPropertyChanged接口。

如果项目被替换了怎么办?那么事件处理程序也应该被删除,对吗?这是如何工作的? - Jordan
你需要移除那个"else"兄弟。从我写评论以来,根据我所读的内容,当索引器的setter被使用时,应该使用replace。因此,第三个选项可能更好。 ;) - Jordan
@Jordan:你关于else的说法是正确的。已经修复了。然而,你不需要第三个选项。 - Daniel Hilgarth
如果 (e.OldItems != null) { foreach (ODataQueryClauseViewModel item in e.OldItems) { item.PropertyChanged -= XXXChanged; } }如果 (e.NewItems != null) { foreach (ODataQueryClauseViewModel item in e.NewItems) { item.PropertyChanged += XXXChanged; } } - RainCast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接