CollectionChanged - 集合名称
CollectionChanged - Name of Collection
我已经像这里一样为 ObservableCollection 实现了 CollectionChanged:
Implementing CollectionChanged
是否有可能在 OnCollectionChanged 方法中找出更改的 属性 的名称是什么?
编辑:
如果 class 有任何变化,则应写入历史记录。
我想实现三种情况:
- "Normal" 属性 改变了(string, int, ...): this is already
工作
- 在集合中添加和删除:如果我知道已更改集合的名称就可以工作
集合中的 属性 已更改:与 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)
}
}
这是正确的:
Children = new ObservableCollection<SomeModel>();
Children.CollectionChanged += Oberservable_CollectionChanged;
尽管您必须确保没有人会更改集合,例如像这样:
public ObservableCollection<SomeModel> Children { get; }
或者在 setter.
中使其成为完整的 属性 和 subscribing/unsubscribing
现在关于 Oberservable_CollectionChanged
处理程序:
- Add and remove in collections: would be working if I know the name of the changed collection
将 sender
添加到您的活动中。
将参数包装到 ...EventArgs
class 中(使其不可变),参见 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
}
- Property inside a collection is changed: same problem as 2) I don't know the name (and index) of the ch
将事件处理程序包装到包含事件处理程序和您需要的值的实例中(我将把该任务留给您)。如果不需要取消订阅,这可以通过使用 lamdba 闭包轻松实现:
foreach (var added in e.NewItems.OfType<INotifyPropertyChanged>)
{
added.PropertyChanged += (s, e) =>
{
// you have `sender` here in addition to `s`, clever?
};
}
我已经像这里一样为 ObservableCollection 实现了 CollectionChanged: Implementing CollectionChanged
是否有可能在 OnCollectionChanged 方法中找出更改的 属性 的名称是什么?
编辑: 如果 class 有任何变化,则应写入历史记录。 我想实现三种情况:
- "Normal" 属性 改变了(string, int, ...): this is already 工作
- 在集合中添加和删除:如果我知道已更改集合的名称就可以工作 集合中的
属性 已更改:与 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) } }
这是正确的:
Children = new ObservableCollection<SomeModel>();
Children.CollectionChanged += Oberservable_CollectionChanged;
尽管您必须确保没有人会更改集合,例如像这样:
public ObservableCollection<SomeModel> Children { get; }
或者在 setter.
中使其成为完整的 属性 和 subscribing/unsubscribing现在关于 Oberservable_CollectionChanged
处理程序:
- Add and remove in collections: would be working if I know the name of the changed collection
将 sender
添加到您的活动中。
将参数包装到 ...EventArgs
class 中(使其不可变),参见 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
}
- Property inside a collection is changed: same problem as 2) I don't know the name (and index) of the ch
将事件处理程序包装到包含事件处理程序和您需要的值的实例中(我将把该任务留给您)。如果不需要取消订阅,这可以通过使用 lamdba 闭包轻松实现:
foreach (var added in e.NewItems.OfType<INotifyPropertyChanged>)
{
added.PropertyChanged += (s, e) =>
{
// you have `sender` here in addition to `s`, clever?
};
}