C# WPF将项添加到BindingList不会更新Viewmodel中的另一个属性
我的viewmodel Singleton中有以下代码:C# WPF将项添加到BindingList不会更新Viewmodel中的另一个属性,c#,wpf,mvvm,bindinglist,C#,Wpf,Mvvm,Bindinglist,我的viewmodel Singleton中有以下代码: /// <summary> /// Gets or sets the person list. /// </summary> /// <value> /// The person list. /// </value> public BindingList<Person> PersonList { ge
/// <summary>
/// Gets or sets the person list.
/// </summary>
/// <value>
/// The person list.
/// </value>
public BindingList<Person> PersonList
{
get { return personList; }
set
{
personList = value;
OnPropertyChanged(nameof(PersonList));
OnPropertyChanged(nameof(PersonCount));
}
}
/// <summary>
/// Gets the person count.
/// </summary>
/// <value>
/// The person count.
/// </value>
public int PersonCount
{
get
{
return personList.Count();
}
}
为什么PersonCount没有更新,如何正确更新?
我做错了什么
提前感谢,,
Andreas您必须调用OnPropertyChangednameofPersonCount;您可以在其中修改列表。如果不可能,那么您必须在setter中订阅CollectionChanged for PersonList并调用OnPropertyChangednameofPersonCount;在事件处理程序中。您必须调用OnPropertyChangednameofPersonCount;您可以在其中修改列表。如果不可能,那么您必须在setter中订阅CollectionChanged for PersonList并调用OnPropertyChangednameofPersonCount;在事件处理程序中。代码中的问题是,一旦您将“PersonList”绑定到视图模型,列表对象不会更改,除非您绑定另一个列表,否则只会在列表中添加或删除项目,因此不会调用“PersonList”属性的setter&因此不会触发“PersonCount”的Notify属性更改
public BindingList<Person> PersonList
{
get { return personList; }
set
{
if (personList != null)
personList.ListChanged -= PersonList_ListChanged;
personList = value;
if (personList != null)
personList.ListChanged += PersonList_ListChanged;
OnPropertyChanged(nameof(PersonList));
}
}
public PersonsDashboardViewModel()
{
PersonList = new BindingList<Person>();
PersonList.Add(new Person("Name1", "Lname1"));
PersonList.Add(new Person("Name2", "Lname2"));
}
private void PersonList_ListChanged(object sender, ListChangedEventArgs e)
{
OnPropertyChanged(nameof(PersonCount));
}
但是,由于“PersonList”是一个绑定列表,因此添加/删除的项会反映在UI中
解决方案
1将“PersonList”注册到ListChanged事件,并在事件处理程序中调用“Notify Property Changed”
public BindingList<Person> PersonList
{
get { return personList; }
set
{
if (personList != null)
personList.ListChanged -= PersonList_ListChanged;
personList = value;
if (personList != null)
personList.ListChanged += PersonList_ListChanged;
OnPropertyChanged(nameof(PersonList));
}
}
public PersonsDashboardViewModel()
{
PersonList = new BindingList<Person>();
PersonList.Add(new Person("Name1", "Lname1"));
PersonList.Add(new Person("Name2", "Lname2"));
}
private void PersonList_ListChanged(object sender, ListChangedEventArgs e)
{
OnPropertyChanged(nameof(PersonCount));
}
代码中的问题是,一旦您将“PersonList”绑定到视图模型,列表对象就不会更改,除非您绑定另一个列表。所发生的只是从列表中添加或删除项,因此不会调用“PersonList”属性的setter&因此不会触发“PersonCount”的Notify属性更改 但是,由于“PersonList”是一个绑定列表,因此添加/删除的项会反映在UI中 解决方案 1将“PersonList”注册到ListChanged事件,并在事件处理程序中调用“Notify Property Changed”
public BindingList<Person> PersonList
{
get { return personList; }
set
{
if (personList != null)
personList.ListChanged -= PersonList_ListChanged;
personList = value;
if (personList != null)
personList.ListChanged += PersonList_ListChanged;
OnPropertyChanged(nameof(PersonList));
}
}
public PersonsDashboardViewModel()
{
PersonList = new BindingList<Person>();
PersonList.Add(new Person("Name1", "Lname1"));
PersonList.Add(new Person("Name2", "Lname2"));
}
private void PersonList_ListChanged(object sender, ListChangedEventArgs e)
{
OnPropertyChanged(nameof(PersonCount));
}
你的第一点很危险!如果再次将PersonList设置为不在PersonsDashboardViewModel的构造函数中,则UI将不会更新。你必须更仔细地阅读我的回答你的第一个解决方案起了作用。我使用带有BusinessLogic的单独类来更改viewmodel。OnPropertyChanged方法也是私有的。因此,我无法在此BusinessLogic中使用viewmodel的OnPropertyChanged方法。同意@Rekshino,注册事件时必须小心。在“PersonList”的setter中注册“ListChanged”事件很简单。现在看起来更好了。你的第1点很危险!如果再次将PersonList设置为不在PersonsDashboardViewModel的构造函数中,则UI将不会更新。你必须更仔细地阅读我的回答你的第一个解决方案起了作用。我使用带有BusinessLogic的单独类来更改viewmodel。OnPropertyChanged方法也是私有的。因此,我无法在此BusinessLogic中使用viewmodel的OnPropertyChanged方法。同意@Rekshino,注册事件时必须小心。在“PersonList”的setter中注册“ListChanged”事件很简单。现在看起来好多了。谢谢您的回答。我的Personlist在构造函数中分别以重置方法实例化,以便在需要时重置viewmodel。这就是你对塞特的意思吗?提前谢谢。@AndreasSusewind如果在重置方法中重新分配列表,则必须取消订阅以前的事件处理程序并设置新的事件处理程序。普拉博达已经改变了答案,现在是塞特订阅。谢谢你的回答。我的Personlist在构造函数中分别以重置方法实例化,以便在需要时重置viewmodel。这就是你对塞特的意思吗?提前谢谢。@AndreasSusewind如果在重置方法中重新分配列表,则必须取消订阅以前的事件处理程序并设置新的事件处理程序。普拉博达改变了答案,现在是在塞特订阅。