CollectionChanged - 集合名称

时间:2017-07-03 09:01:33

标签: c# inotifycollectionchanged

我已经为ObservableCollection实现了CollectionChanged,就像这里一样: Implementing CollectionChanged

OnCollectionChanged方法是否有可能找出更改后的属性的名称是什么?

修改 如果班级有任何变化,应写下历史。 我想要实现三种情况:

  1. “正常”属性已更改(字符串,整数,...):这已经是 工作
  2. 在集合中添加和删除:如果我知道已更改集合的名称,则可以正常工作
  3. 集合中的属性发生了变化:同样的问题2)我不知道ch的名称(和索引)

    public class ParentClass : BaseModel
    {
        public ParentClass()
        {
            Children = new ObservableCollection<SomeModel>();
            Children.CollectionChanged += Oberservable_CollectionChanged;
        }
    
        private string id;
    
        public string Id
        {
            get
            {
                return id;
            }
            set
            {
                string oldId = id;
                id = value;
                OnPropertyChanged(oldArticleId,id);
            }
        }
    
        public ObservableCollection<SomeModel> Children { get; set; }
    
        protected virtual void OnPropertyChanged(object oldValue, object newValue, [CallerMemberName] string propertyName = null)
        {
            //1) Entry is added to history (this part is working)
        }
    
    
        protected void Oberservable_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.NewItems != null)
            {
                foreach (INotifyPropertyChanged added in e.NewItems)
                {
                    added.PropertyChanged += OnPropertyChangedHandler;
                    OnCollectionChanged(CollectionChangedModel.Action.Added, added);
                }
            }
    
            if (e.OldItems != null)
            {
                foreach (INotifyPropertyChanged removed in e.OldItems)
                {
                    removed.PropertyChanged -= OnPropertyChangedHandler;
                    OnCollectionChanged(CollectionChangedModel.Action.Removed, removed);
                }
            }
        }
    
        protected virtual void OnCollectionChanged(CollectionChangedModel.Action action, object value)
        {
            //2) TODO: History should be written, but I don't have the property name
        }
    
        public void OnPropertyChangedHandler(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
        {
            //3) TODO: History about changed property in child-class (not working because of missing property name and index)
        }
    }
    

1 个答案:

答案 0 :(得分:1)

这是正确的:

Children = new ObservableCollection<SomeModel>();
Children.CollectionChanged += Oberservable_CollectionChanged;

虽然您必须确保没有人会更改收藏,例如像这样:

public ObservableCollection<SomeModel> Children { get; }

或者更确切地说,它是一个完整的属性,并在setter中订阅/取消订阅。

现在关于Oberservable_CollectionChanged处理程序:

  
      
  1. 在集合中添加和删除:如果我知道已更改集合的名称,则可以正常工作
  2.   

为您的活动添加sender。 将参数包装到...EventArgs类中(使其成为不可变的),请参阅msdn

public event EventHandler<MyCollectionChangedEventArgs> CollectionChanged;
protected virtual void OnCollectionChanged(object sender, MyCollectionChangedEventArgs e)
{
    //2) TODO: History should be written, but I don't have the property name

    // sender is name
    // e.Action and e.Value are parameters
}
  
      
  1. 集合中的属性发生了变化:同样的问题2)我不知道ch的名称(和索引)
  2.   

将事件处理程序包装到包含事件处理程序和所需值的实例中(我将为您保留该任务)。如果不需要取消订阅,可以使用lamdba闭包轻松实现:

foreach (var added in e.NewItems.OfType<INotifyPropertyChanged>)
{
    added.PropertyChanged += (s, e) => 
    {
        // you have `sender` here in addition to `s`, clever?
    };
}