这是C#中的数据绑定问题。
我有一个简单的Person类:
public class Person {
public string Name {get; set;}
public string Level {get; set;}
}
我有一个Group类,它包含一个Persons属性作为Person实例的BindingList:
public class Group {
private BindingList<Person> persons_;
public BindingList<Person> Persons {
get { return persons_; }
set { persons_ = value; }
}
}
最后,我使用BindingSource将组实例连接到DataGridView:
// Instantiate a Group instance.
Group p = new Group();
p.Persons = new BindingList<Person> {
new Person {Name = "n1", Level = "l1"},
new Person {Name = "n2", Level = "l2"},
new Person {Name = "n3", Level = "l3"}
};
BindingSource bs = new BindingSource();
bs.DataSource = p;
bs.DataMember = "Persons";
DataGridView dgv = new DataGridView();
dgv.DataSource = bs;
在上面的代码之后,DataGridView将显示三个Person实例。一切正常。然后我有一个按钮,当单击按钮时,我创建另一个Person BindingList并用它来替换p.Persons:
p.Persons = new BindingList<Person> {
new Person {Name = "n10", Level = "l10"},
new Person {Name = "n11", Level = "l11"},
new Person {Name = "n12", Level = "l12"}
};
在上面的代码之后,数据绑定停止工作。从BindingSource或DataGridView添加ResetBindings()调用并不能解决数据绑定的中断问题。
由于我的BindingSource绑定到Group类的Persons属性,我认为Persons属性的更改不应该破坏数据绑定,但事实上它确实如此。但这是我们通常在将字符串属性绑定到Label或TextBox时所做的事情。我们只是为属性分配一个新的字符串实例,Label或TextBox将正确更新。为什么这不适用于实例集合?实现相同行为的正确代码是什么?非常感谢你。
答案 0 :(得分:2)
您的数据模型非常错误:Collection properties should be readonly。
相反,您应该移除Persons
二传手,然后清除列表并反复拨打Add
。
如果您愿意,您甚至可以创建扩展方法
public static void ReplaceWith<T>(this IList<T> list, params T[] newItems)
答案 1 :(得分:1)
这是因为Persons
属性在更改时不会触发通知。 Group
类应该实现INotifyPropertyChanged
,Persons
属性的setter应该引发PropertyChanged
事件。