触发INotifyPropertyChanged的/ CollectionChanged上的ObservableCollection [英] Trigger InotifyPropertyChanged/CollectionChanged on ObservableCollection

查看:289
本文介绍了触发INotifyPropertyChanged的/ CollectionChanged上的ObservableCollection的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着看这个其他话题,但我还没有找到一个工作实现我的问题。基本上,我有一个ObservableCollection称为包含不同种类的水果水果篮。水果篮本身含有的 ObservableCollections 的用于通过传递,以便它们可以被用作<青霉> ItemSources 的每个相应类型的水果的列表视图的(通过名称表示 AppleContainer和OrangeContainer),显示每一种水果。因为水果类本身实现INotifyPropertyChanged,修改它们的值触发更新到ListView控件就好了,但是,水果篮已经从馆藏中的所有其他水果的权重得出的TotalWeight属性。我想TotalWeight更新的标签的控制在UI中没有我不必刷新UI。实际的的ObservableCollection 的本身,而不是简单的组成成员是比较困难的,我还没有发现工作至今任何解决方案(或者说我已经正确实施)的属性变化Triggerering的通知

 公共类水果篮:与的ObservableCollection LT; IFruit> 
{
私人小数_totalWeight;

公共水果篮()
{
this.Add(新OrangeContainer(本));
this.Add(新AppleContainer(本));
}

公共OrangeContainer橙子
{
{返回(OrangeContainer)this.Items [0]; }
}

公共AppleContainer苹果
{
{返回(AppleContainer)this.Items [1]; }
}

公共小数TotalWeight
{
{返回_totalWeight; }
集合{_totalWeight =价值; }
}

内部空隙UpdateWeight(IFruit调用者)
{
_totalWeight = 0;
的foreach(橙色ORNG在(OrangeContainer)this.Items [0])
{
_totalWeight + = orng.Weight;
}
的foreach(苹果申请中(AppleContainer)this.Items [1])$ ​​B $ B {
_totalWeight + = appl.Weight;
}
}


解决方案

您。每当需要项目被添加,删除或任何商品的重量属性发生变化时打电话给你的水果篮的INotifyPropertyChanged.PropertyChanged事件



可以把它分成两个任务:



<醇>
  • 当添加项,删除或项的权重被改变TotalWeight应重新计算。我们需要处理的事件。

  • 提高FruitBasket.PropertyChanged事件



  • 我这些分裂两个任务分为两类,以遵循单一职责原则:



    1) - 此处理项目的PropertyChanged事件:

     公共抽象类ExtendedObservableCollection< T> :与的ObservableCollection LT; T>其中T:INotifyPropertyChanged的
    {
    保护覆盖无效ClearItems()
    {
    的foreach(VAR在项目项目)item.PropertyChanged - = ItemPropertyChanged;
    base.ClearItems();
    }

    保护覆盖无效InsertItem(INT指数,T项目)
    {
    item.PropertyChanged + = ItemPropertyChanged;
    base.InsertItem(索引项);
    }

    保护覆盖无效的removeItem(INT指数)
    {
    本[指数] .PropertyChanged - = ItemPropertyChanged;
    base.RemoveItem(指数);
    }

    保护覆盖无效SetItem(INT指数,T项目)
    {
    本[指数] .PropertyChanged - = ItemPropertyChanged;
    item.PropertyChanged + = ItemPropertyChanged;
    base.SetItem(索引项);
    }

    抽象无效ItemPropertyChanged(对象发件人,PropertyChangedEventArgs E);
    }



    2) - 这重新计算TotalWeight必要时



     公共类水果篮:ExtendedObservableCollection< IFruit> 
    {
    保护覆盖无效ItemPropertyChanged(对象发件人,PropertyChangedEventArgs E){
    UpdateWeight();
    OnPropertyChanged(TotalWeight)
    }

    保护覆盖无效OnCollectionChanged(NotifyCollectionChangedEventArgs E)
    {
    UpdateWeight();
    OnPropertyChanged(TotalWeight)
    base.OnCollectionChanged(E);
    }
    }



    当然,你们的果子实现INotifyPropertyChanged接口。你会发现例子plety如何做到这一点。这是非常简单的。


    I've tried looking at other topics on this but I haven't found a working implementation to my question. Basically, I have an ObservableCollection called "FruitBasket" that contains different kinds of fruit. FruitBasket itself contains ObservableCollections for each respective type of fruit that passes through so that they can be used as ItemSources for ListViews (Denoted by their names "AppleContainer" and "OrangeContainer"), each displaying one kind of fruit. Because the fruit classes themselves implement INotifyPropertyChanged, modifying their values triggers updates to the ListView controls just fine, however, FruitBasket has a "TotalWeight" property derived from the weights of all the other fruits in the collections. I want "TotalWeight" to update the Label control in the UI without me having to refresh the UI. Triggerering a notification on a property change of the actual ObservableCollection itself, and not simply its constituent members is more difficult and I haven't found any solutions that work so far (or that I've implemented correctly).

    public class FruitBasket : ObservableCollection<IFruit>
    {
        private decimal _totalWeight;
    
        public FruitBasket()
        {
            this.Add(new OrangeContainer(this));
            this.Add(new AppleContainer(this));
        }
    
        public OrangeContainer Oranges
        {
            get { return (OrangeContainer)this.Items[0]; }
        }
    
        public AppleContainer Apples
        {
            get { return (AppleContainer)this.Items[1]; }
        }
    
        public decimal TotalWeight
        {
            get { return _totalWeight; }
            set { _totalWeight = value; }
        }
    
        internal void UpdateWeight(IFruit caller)
        {
            _totalWeight = 0;
            foreach (Orange orng in (OrangeContainer)this.Items[0])
            {
                _totalWeight += orng.Weight;
            }
            foreach (Apple appl in (AppleContainer)this.Items[1])
            {
                _totalWeight += appl.Weight;
            }
        }
    

    解决方案

    You need to call INotifyPropertyChanged.PropertyChanged event of your FruitBasket whenever items are added, removed or Weight property of any item has changed.

    lets split it into two tasks:

    1. TotalWeight should be recalculated when items are added, removed, or items' weight is changed. We need to handle those events.
    2. Raise FruitBasket.PropertyChanged event

    I have splitted these two tasks into two classes in order to follow Single Responsibility Principle:

    1) - this handles items' PropertyChanged events:

    public abstract class ExtendedObservableCollection<T> : ObservableCollection<T> where T : INotifyPropertyChanged
    {
        protected override void ClearItems()
        {
            foreach (var item in Items) item.PropertyChanged -= ItemPropertyChanged;
            base.ClearItems();
        }
    
        protected override void InsertItem(int index, T item)
        {
            item.PropertyChanged += ItemPropertyChanged;
            base.InsertItem(index, item);
        }
    
        protected override void RemoveItem(int index)
        {
            this[index].PropertyChanged -= ItemPropertyChanged;
            base.RemoveItem(index);
        }
    
        protected override void SetItem(int index, T item)
        {
            this[index].PropertyChanged -= ItemPropertyChanged;
            item.PropertyChanged += ItemPropertyChanged;
            base.SetItem(index, item);
        }
    
        abstract void ItemPropertyChanged(object sender, PropertyChangedEventArgs e);
    }
    

    2) - this recalculates TotalWeight when necessary

    public class FruitBasket : ExtendedObservableCollection<IFruit>
    {
        protected override void ItemPropertyChanged(object sender, PropertyChangedEventArgs e){
            UpdateWeight();
            OnPropertyChanged("TotalWeight")
        }
    
        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            UpdateWeight();
            OnPropertyChanged("TotalWeight")
            base.OnCollectionChanged(e);
        }
    }
    

    Of course your Fruit should implement INotifyPropertyChanged interface. You will find plety of examples how to do it. it is very simple.

    这篇关于触发INotifyPropertyChanged的/ CollectionChanged上的ObservableCollection的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆