如何为INotifyPropertyChanged接口创建自己的PropertyChangedEventArgs?

时间:2012-08-16 15:39:14

标签: c# .net class events mvvm

我遇到了一个问题,即DataModelViewModelPropertyChanged event之间的无限循环。

我的结构:

public class SomeDataModel : DataModelBase
{
    public SomeDataModel()
    {

    }

    public object SomeProperty
    {
        get
        {
            //
        }
        set;
        {
            //
            OnPropertyChanged("SomeProperty");
        }
    }

    public bool SomeMethod()
    {
        SomeProperty = SomeNewObject
    }
}

public class SomeViewModel : ViewModelBase
{
    public SomeViewModel()
    {

    }

    public SomeDataModel SomeDataModel
    {
        get;
        set;
    }

    public object SomeProperty
    {
        get
        {
            return SomeDataModel.SomeProperty;
        }
        set
        {
            SomeDataModel.SomeProperty = value;
            OnPropertyChanged("SomeProperty");
        }
    }
}

ViewModelDataModel都实现了INotifyPropertyChanged

然后我的listener ViewModelBaseproperty DataModel private void DataModel_PropertyChanged(object sender, PropertyChangedEventArgs e) { PropertyInfo toPropertyInfo = this.GetType().GetProperty(e.PropertyName); PropertyInfo fromPropertyInfo = DataModel.GetType().GetProperty(e.PropertyName); if (toPropertyInfo != null && fromPropertyInfo != null) { if (toPropertyInfo.CanWrite && fromPropertyInfo.CanRead) { toPropertyInfo.SetValue(this, fromPropertyInfo.GetValue(DataModel, null), null); } } } property发生变化DataModel

ViewModelBase

现在,当property设置ViewModel时,ViewModel中的听众会抓住它并更新DataModel中的相关OnPropertyChanged("SomeProperty");。但是PropertyChangedEventArgs中的集合将其设置回INotifyPropertyChanged,原因public class CustomPropertyChangedEventArgs : PropertyChangedEventArgs { public CustomPropertyChangedEventArgs(string propertyName, SomeEnum enumName) : base(propertyName) { //Set enum } } 会触发agian,以无限循环结束。

  1. 有快速解决方法吗? (注意:无法更改结构)
  2. 我是否可以创建自己的自定义类,继承自OnPropertyChanged并且仍然可以使用CustomPropertyChangedEventArgs操作?
  3. 我在想:

    enum

    然后在public void OnPropertyChanged(string propertyName) { CustomPropertyChangedEventArgs handler = this.PropertyChanged; if (handler != null) { handler(this, new CustomPropertyChangedEventArgs(propertyName, newEnum)); } } 我想使用新的{{1}}并传递我想要使用的{{1}}。

    {{1}}

2 个答案:

答案 0 :(得分:5)

您可以检查值是否相同但不更新。这通常是INotifyPropertyChanged的实现方式。只有在真的更改时才会触发OnPropertyChanged

public object SomeProperty
{
    get
    {
        return SomeDataModel.SomeProperty;
    }
    set
    {
        if (SomeDataModel.SomeProperty != value)
        {
            SomeDataModel.SomeProperty = value;
            OnPropertyChanged("SomeProperty");
        }
    }
}

答案 1 :(得分:0)

you can disable and enable the event to avoid loop
private void DataModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    OnPropertyChanged -= DataModel_PropertyChanged;
    PropertyInfo toPropertyInfo = this.GetType().GetProperty(e.PropertyName);
    PropertyInfo fromPropertyInfo = DataModel.GetType().GetProperty(e.PropertyName);

    if (toPropertyInfo != null && fromPropertyInfo != null)
    {
        if (toPropertyInfo.CanWrite && fromPropertyInfo.CanRead)
        {
            toPropertyInfo.SetValue(this, fromPropertyInfo.GetValue(DataModel, null), null);
        }
    }
    OnPropertyChanged += DataModel_PropertyChanged;
}