INotifyPropertyChanged不能用于XML序列化



我有一个绑定到集合的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方法,所以它不会触发当属性值没有改变。

相关内容

  • 没有找到相关文章

最新更新