0

DataModelmyとViewModelwithの間で無限ループに陥る問題に遭遇しましたPropertyChanged 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私の中で変​​化するもののViewModelBaseために私のproperty中にあります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。しかし、セット内のセットがwithViewModelに戻ると、エイジアンが発火し、無限ループに陥ります。DataModelOnPropertyChanged("SomeProperty");

  1. それを修正するための簡単な回避策はありますか?(: 構造を変更することはできません)
  2. から継承して独自のカスタム クラスを作成しPropertyChangedEventArgs、引き続きINotifyPropertyChanged操作を実行することはできますか?

私が考えていた:

public class CustomPropertyChangedEventArgs : PropertyChangedEventArgs
{
    public CustomPropertyChangedEventArgs(string propertyName, SomeEnum enumName)
        : base(propertyName)
    {
        //Set enum
    }
}

次にOnPropertyChanged、新しいものを使用して、使用したいものCustomPropertyChangedEventArgsを渡しenumます。

public void OnPropertyChanged(string propertyName)
{
    CustomPropertyChangedEventArgs handler = this.PropertyChanged;

    if (handler != null)
    {
        handler(this, new CustomPropertyChangedEventArgs(propertyName, newEnum));
    }
}
4

2 に答える 2

5

値が同じかどうかを確認し、更新しないでください。通常INotifyPropertyChangedはこのように実装されます。本当に変更されたOnPropertyChanged場合にのみ発火します。

public object SomeProperty
{
    get
    {
        return SomeDataModel.SomeProperty;
    }
    set
    {
        if (SomeDataModel.SomeProperty != value)
        {
            SomeDataModel.SomeProperty = value;
            OnPropertyChanged("SomeProperty");
        }
    }
}
于 2012-08-16T15:47:09.890 に答える
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;
}
于 2012-08-16T15:56:04.977 に答える