我的目标是创建一个列表,当元素中的元素发生变化时,该列表将触发事件。我的想法是创建一个实现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));
}
}在这段代码中,ListChanged事件在foreach循环中的列表中添加新实体时触发,而不是在BindingList中触发实体的PropertyChanged时触发( NotifyPropertyChanged方法中的断点停止,但ListChanged事件不会触发)
发布于 2019-09-15 04:42:51
好了,弄清楚了,问题是由于在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");
}));
}
}https://stackoverflow.com/questions/57937226
复制相似问题