ItemPropertyChanged not working on observableCollection.Why?

后端 未结 2 1861
慢半拍i
慢半拍i 2020-12-01 17:47

I have searched high and low for a solution but I dont seem to get to the bottom of it. Like many posts on the net I dont seem to make my itemPropertyChanged work. It does n

相关标签:
2条回答
  • 2020-12-01 18:12
        INotifyPropertyChanged inpc = OrderViewModels;
        inpc.PropertyChanged += OnItemPropertyChanged; 
    

    That code will notify you when any property on the ObservableCollection<T> changes, not when items in the ObservableCollection<T> have their properties changed. For example, your handler should be called when you add or remove an OrderViewModel because the Count property will change on the ObservableCollection<OrderViewModel>.

    Nothing is propagating the PropertyChanged event inside OrderViewModels and aggregating them into a single event for you. I use a class I called ItemObservableCollection when I want to do this:

    public sealed class ItemObservableCollection<T> : ObservableCollection<T>
        where T : INotifyPropertyChanged
    {
        public event EventHandler<ItemPropertyChangedEventArgs<T>> ItemPropertyChanged;
    
        protected override void InsertItem(int index, T item)
        {
            base.InsertItem(index, item);
            item.PropertyChanged += item_PropertyChanged;
        }
    
        protected override void RemoveItem(int index)
        {
            var item= this[index];
            base.RemoveItem(index);
            item.PropertyChanged -= item_PropertyChanged;
        }
    
        protected override void ClearItems()
        {
            foreach (var item in this)
            {
                item.PropertyChanged -= item_PropertyChanged;
            }
    
            base.ClearItems();
        }
    
        protected override void SetItem(int index, T item)
        {
            var oldItem = this[index];
            oldItem.PropertyChanged -= item_PropertyChanged;
            base.SetItem(index, item);
            item.PropertyChanged += item_PropertyChanged;
        }
    
        private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            OnItemPropertyChanged((T)sender, e.PropertyName);
        }
    
        private void OnItemPropertyChanged(T item, string propertyName)
        {
            var handler = this.ItemPropertyChanged;
    
            if (handler != null)
            {
                 handler(this, new ItemPropertyChangedEventArgs<T>(item, propertyName));
            }
        }
    }
    
    public sealed class ItemPropertyChangedEventArgs<T> : EventArgs
    {
        private readonly T _item;
        private readonly string _propertyName;
    
        public ItemPropertyChangedEventArgs(T item, string propertyName)
        {
            _item = item;
            _propertyName = propertyName;
        }
    
        public T Item
        {
            get { return _item; }
        }
    
        public string PropertyName
        {
            get { return _propertyName; }
        }
    }
    

    I can use it like this:

    var orders = new ItemObservableCollection<OrderViewModel>();
    orders.CollectionChanged   += OnOrdersChanged;
    orders.ItemPropertyChanged += OnOrderChanged;
    
    0 讨论(0)
  • 2020-12-01 18:13

    System.ComponentModel.BindingList<Type> offer the same functionnality as ObservableCollection<Type> and handles the PropertyChanged events correctly.

    Best regards

    0 讨论(0)
提交回复
热议问题