我的目标是创建一个列表,当元素中的元素发生更改时将触发事件。想法是创建一个实现了INotifyChanged的实体的BindingList,以将该事件转发到ViewModel。
我目前所拥有的:
public class ViewModel
{
public TagPresenter Tags {get;}
public ViewModel()
{
Tags = new TagPresenter();
Tags.TagCollection.ListChanged += (object o, ListChangedEventargs e) => { DataAccessor.UpdateTag(o[e.NewIndex]); };
foreach(var tag in DataAccessor.GetTags())
Tags.TagCollection.Add(new TagEntity(tag, Tags.TagCollection));
}
}
public class TagPresenter
{
public BindingList<object> TagCollection {get;}
public TagPresenter()
{
TagCollection = new BindingList<object>();
}
}
public class TagEntity : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged {get;}
public Command ChangeState {get;}
public TagEntity(string tag, BindingList<object> parent)
{
ChangeState = new Command(new Action(() => {
NotifyPropertyChanged("Property");
}));
}
public void NotifyPropertyChanged(string _property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_property));
}
}
在此代码中,将新实体添加到foreach循环中的列表中时触发ListChanged事件,但当我触发BindingList中的实体的PropertyChanged时触发(NotifyPropertyChanged方法中的断点停止,但ListChanged事件不会触发)
答案 0 :(得分:0)
好,知道了,问题出在与BindingList中对象之间的TagEntity装箱/拆箱。一旦我添加了实现INotifyChanged的抽象类TagBase,并将集合切换到BindingList,它便可以按预期工作:
public class ViewModel
{
public TagPresenter Tags {get;}
public ViewModel()
{
Tags = new TagPresenter();
Tags.TagCollection.ListChanged += (object o, ListChangedEventargs e) => { DataAccessor.UpdateTag(o[e.NewIndex]); };
foreach(var tag in DataAccessor.GetTags())
Tags.TagCollection.Add(new TagEntity(tag, Tags.TagCollection));
}
}
public class TagPresenter
{
public BindingList<TagBase> TagCollection {get;}
public TagPresenter()
{
TagCollection = new BindingList<TagBase>();
}
}
public abstract class TagBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged {get;}
public void NotifyPropertyChanged(string _property)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(_property));
}
}
public class TagEntity : TagBase
{
public Command ChangeState {get;}
public TagEntity(string tag, BindingList<TagBase> parent)
{
ChangeState = new Command(new Action(() => {
NotifyPropertyChanged("Property");
}));
}
}