11

多分ここにそのような質問がありますが、私はそれを見つけられませんでした。

私はMVVMアプリケーションをViewModel持っており、いくつかのプロパティの変更に対して追加のアクションを実行する必要があります(たとえば、Viewそれらを変更する場合)。どちらのアプローチがあなたにとってより良いと思いますか?またその理由は何ですか?

1st -AdditionalActionセッターへの呼び出しを追加する

public class ViewModel: INotifyPropertyChanged
{
  private int _MyProperty;

  public int MyProperty
  {
    get { return _MyProperty; }
    set
    {
      if (_MyProperty == value) return;
      _MyProperty = value;
      RaisePropertyChanged(() => MyProperty);

      // --- ADDITIONAL CODE ---
      AdditionalAction();
    }
  }
}

2 番目 - INotifyPropertyChanged へのセルフサブスクライブ

public class ViewModel: INotifyPropertyChanged
{
  public ViewModel()
  {
    // --- ADDITIONAL CODE ---
    PropertyChanged += OnPropertyChanged;
  }

  private int _MyProperty;

  public int MyProperty
  {
    get { return _MyProperty; }
    set
    {
      if (_MyProperty == value) return;
      _MyProperty = value;
      RaisePropertyChanged(() => MyProperty);
    }
  }

  void PropertyChanged(object sender, PropertyChangedEventArgs e)
  {
    // --- ADDITIONAL CODE ---
    if (e.PropertyName == "MyProperty")
      AdditionalAction();
  }
}

パフォーマンスの問題や 10,000 個のオブジェクトがないことを想像してみてください。View と ViewModel だけです。何が良いですか?最初のコードは「小さく」なり、オーバーヘッドが少なくなりますが、2 番目のコード (私の考えでは) はより明確になり、自動生成プロパティのコードにコード スニペットを使用できます。さらに-2番目のケースでは、イベントハンドラーに次のようなものを書くことができます:

On.PropertyChanged(e, p => p.MyProperty, AdditionalAction);

Onクラスヘルパーはどこですか。

それで、あなたの心には何が良いですか、そしてその理由は何ですか?

更新しました:

OK、まだ1つのアプローチを見つけたようです:

3番目 - RaisePropertyChanged に「拡張ポイント」を追加します。

public class NotificationObject : INotifyPropertyChanged
{
  void RaisePropertyChanged(Expression<...> property)
  {
    // ... Raise PropertyChanged event
    if (PropertyChanged != null)
      // blah-blah

    // Call extension point
    OnPropertyChanged(property.Name);
  }

  public virtual OnPropertyChanged(string propertyName)
  {
  }
}

public class ViewModel: NotificationObject
{
  private int _MyProperty;

  public int MyProperty
  {
    get { return _MyProperty; }
    set
    {
      if (_MyProperty == value) return;
      _MyProperty = value;
      RaisePropertyChanged(() => MyProperty);
    }
  }

  override OnPropertyChanged(string propertyName)
  {
    if (propertyName == "MyProperty")
      AdditionalAction();
  }
}

この方法ではイベントを使用しませんが、すべての「追加アクション」は同じ「拡張ポイント」から呼び出されます。「透明でないワークフロー」よりも「すべての追加アクションを 1 か所で」の方がよいですか?

4

2 に答える 2

3

これが「通常の」パターンです。これにより、プロパティ固有のコードをOnXメソッド内に配置でき、派生クラスでも同じことができます。もちろん外部リスナーでない限り、大きなswitchステートメントは必要ありませんが、それはINotifyPropertyChangedのコースと同等です。

public class NotificationObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void FirePropertyChanged(PropertyChangedEventArgs e)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, e);
    }
}

public class ViewModel : NotificationObject
{
    private int _MyProperty1;
    public int MyProperty1
    {
        get { return _MyProperty1; }
        set
        {
            if (value != _MyProperty1)
            {
                _MyProperty1 = value;
                OnMyProperty1Changed(new PropertyChangedEventArgs("MyProperty1"));
            }
        }
    }

    protected virtual void OnMyProperty1Changed(PropertyChangedEventArgs e)
    {
        FirePropertyChanged(e);
    }

    private int _MyProperty2;
    public int MyProperty2
    {
        get { return _MyProperty2; }
        set
        {
            if (value != _MyProperty2)
            {
                _MyProperty2 = value;
                OnMyProperty2Changed(new PropertyChangedEventArgs("MyProperty2"));
            }
        }
    }

    protected virtual void OnMyProperty2Changed(PropertyChangedEventArgs e)
    {
        FirePropertyChanged(e);
    }
}
于 2012-05-04T15:53:23.780 に答える
3

私は間違いなく最初の方法を選びます:

  • それは明確だ
  • 流れと意図が明確である
  • 奇妙な(imo)セルフサブスクリプションを回避します

自動生成されたプロパティを使用できるようにする 2 番目の「利点」は、1 番目のケースの実行フローを明確にする価値はありません。

お役に立てれば。

于 2012-05-04T14:58:19.957 に答える