BindingList <T>不会在编辑时触发ListChanged

时间:2019-09-14 16:12:37

标签: c# inotifypropertychanged bindinglist

我的目标是创建一个列表,当元素中的元素发生更改时将触发事件。想法是创建一个实现了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事件不会触发)

1 个答案:

答案 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");
        }));
    }

}