我有一个绑定到集合的DataGridView。集合中的类型实现了INotifyPropertyChanged(来自MSDN页面的教科书实现)。
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public string Name
{
get { return m_Name; }
set { m_Name = value; NotifyPropertyChanged("Name"); }
}
我试图理解何时,如何以及为什么PropertyChanged事件实际上被解雇。如果我写代码使用名称属性来改变字符串一切工作,PropertyChanged是!= NULL,我的DataGridView更新正确。像这样:
for (int i = 0; i < Server.Customers.Count; i++)
{
Server.Customers[i].Name = Server.Customers[i].Name + "!!";
}
这只是一个测试,然而,集合真正应该更新的方式是通过XML反序列化。序列化器的实现非常简单,代码步进与前面示例中完全相同的Name属性(调用NotifyPropertyChanged)。只有一点不同:PropertyChanged结果是NULL,并且永远不会被调用。结果:我的数据绑定没有更新。
我不太明白这是怎么回事。我从一开始就没有显式地订阅PropertyChanged(我找到的任何代码示例也没有),但是在第一个示例中它被正确调用。在第二个示例中,我将XML反序列化为对象,如何使其工作?
XML序列化不能更新现有对象,它总是在反序列化时创建一个新对象。因为它是一个新对象,所以还没有PropertyChanged
的处理程序,所以没有触发事件。
监听正在创建的对象的PropertyChanged
事件没有意义。你到底想干什么?
我完全同意Thomas的回答,并提出一些建议:
如果你需要使用INotifyPropertyChanges
,你肯定应该用其他方法来反序列化对象。您可以使用InitializeFrom(string xml)
或UpdateFrom(string xml)
这样的实例方法。您创建一个对象,订阅PropertyChanged
事件,然后在现有对象上调用UpdateFrom(xml)
。因此,您将收到更改通知,并保持现有对象的活动状态。在这里,您可以通过以下方式实现整个内容:
class MyClass : INotifyPropertyChanges
{
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
public string Name
{
get { return m_Name; }
set { m_Name = value; NotifyPropertyChanged("Name"); }
}
public void UpdateFrom(string xml)
{
MyClass deserialized = Deserialize(xml);
// here you set all properties you have
Name = deserialized.Name;
// and all the rest properties...
}
private static MyClass Deserialize(string xml)
{
XmlSerializer ser = new XmlSerializer(typeof(MyClass));
using (StringReader reader = new StringReader(xml))
{
return (MyClass)ser.Deserialize(reader);
}
}
}
我也会修改NotifyPropertyChanged
方法,所以它不会触发当属性值没有改变。