web-dev-qa-db-ja.com

WPF依存関係プロパティとINotifyPropertyChangedをいつ使用するか

ビューモデルでINotifyPropertyChanged.PropertyChangedを起動する単純な.NETプロパティで十分な場合についてのガイダンスはありますか?それでは、いつ本格的な依存関係プロパティに移行したいですか?それとも、DPは主にビューを対象としていますか?

35
Keith Hill

いくつかのアプローチがあります:

1。依存関係プロパティ

依存関係プロパティを使用している間、それは要素で最も意味があります-視覚的な外観を持つクラス(UIElements)。

長所:

  • WPFはあなたのために論理的なことをします
  • アニメーションのようないくつかのメカニズムは、依存関係プロパティのみを使用します
  • 「フィット」ViewModelスタイル

短所:

  • フォームDependencyObjectを導出する必要があります
  • 単純なものには少し厄介です

サンプル:

_public static class StoryBoardHelper
{
    public static DependencyObject GetTarget(Timeline timeline)
    {
        if (timeline == null)
            throw new ArgumentNullException("timeline");

        return timeline.GetValue(TargetProperty) as DependencyObject;
    }

    public static void SetTarget(Timeline timeline, DependencyObject value)
    {
        if (timeline == null)
            throw new ArgumentNullException("timeline");

        timeline.SetValue(TargetProperty, value);
    }

    public static readonly DependencyProperty TargetProperty =
            DependencyProperty.RegisterAttached(
                    "Target",
                    typeof(DependencyObject),
                    typeof(Timeline),
                    new PropertyMetadata(null, OnTargetPropertyChanged));

    private static void OnTargetPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        Storyboard.SetTarget(d as Timeline, e.NewValue as DependencyObject);
    }
}
_

2。System.ComponentModel.INotifyPropertyChanged

通常、データオブジェクトを作成するときは、このアプローチを使用します。これは、データのようなもののためのシンプルできちんとしたソリューションです。

長所と短所-1を補完します。1つのイベント(PropertyChanged)のみを実装する必要があります。

サンプル:

_public class Student : INotifyPropertyChanged 
{ 
   public event PropertyChangedEventHandler PropertyChanged; 
   public void OnPropertyChanged(PropertyChangedEventArgs e) 
   { 
       if (PropertyChanged != null) 
          PropertyChanged(this, e); 
   } 
}

private string name; 
public string Name; 
{ 
    get { return name; } 
    set { 
           name = value; 
           OnPropertyChanged(new PropertyChangedEventArgs("Name")); 
        } 
} 
_

3.PropertyNameかわった

指定された名前(例:NameChanged)で各プロパティのイベントを発生させます。イベントにはこの名前を付ける必要があり、それらを処理/発生させるのはあなた次第です。 2と同様のアプローチ。

4.バインディングを取得します

FrameworkElement.GetBindingExpression()を使用すると、BindingExpressionオブジェクトを取得し、BindingExpression.UpdateTarget()を呼び出して更新できます。

あなたの目標が何であるかに応じて、1番目と2番目が最も可能性が高いです。

全体として、それはビジュアル対データです。

53
Lukasz Madon

私の知る限り、DependencyPropertyは必要な場合にのみ必要です

  1. PropertyValueの継承
  2. プロパティをスタイルセッターで設定できるようにする必要があります
  3. プロパティにアニメーションを使用する

等.

これらの機能は、通常のプロパティでは使用できません。

14
abhishek

プロパティにバインディングを設定できるようにする場合は、DependencyPropertyが必要です。通常、これは作成したカスタムUIElements用です。人々がデータをあなたのUIElementsにバインドできるようにしたいのです。

<local:MyUIElement MyProperty={Binding Path=SomethingToBindTo} />

これを行うには、MyPropertyが依存関係プロパティである必要があります

4
CodeMnke

他の回答が依存関係プロパティをいつ作成するかについてすでに十分に述べているように。つまり.

  1. PropertyValueの継承
  2. プロパティにバインディングを使用する必要があります
  3. プロパティにアニメーションを使用する

これに関するもう1つの視点/質問は、「WPFアプリケーションでは、コントロールに依存関係プロパティを作成するのが理にかなっています。これは、高さ、幅、テキスト、コンテンツ、背景などのユーザー操作中に変更される可能性があるためですしかし、Behaviors Classes(非UIクラス)のような他のクラスはどうですか?これらのクラスのプロパティは依存関係プロパティである必要がありますか? "

ここでは、いくつかのルールセットを絶対的または強調することはしませんが、プロパティをDPとして作成する必要があります。デザインの観点から、プロパティがDPの場合、使用/バインドするのは常にデフォルトのWPF形式です。

  1. DPは、通常のCLRプロパティと比較して、変更の反映がはるかに高速で自然です。
  2. DPには、割り当てられた値を検証するための検証メカニズムと、値を元に戻すためのデフォルトの構造があります。
  3. DPには、プロパティの制限を制御するための強制値コールバックがあります。
  4. DPには、CLRプロパティとは異なり、メタデータが関連付けられています。

慣例として、ネストされたバインディングで多くの間違いを犯し、変更を発生させるのを見てきました。この種の障害は、変更自体を発生させる設計と互換性のDPの原因では発生しません。したがって、少し余分な構文を使用して、アプリケーションに柔軟性/パフォーマンス/使いやすさを追加します。だから、手頃な価格ならどこでもそれを選びましょう。

それでも、ViewModelクラス/その他のヘルパークラスについては確信が持てません。将来、説得力のある理由が見つかった場合は、回答を更新します。

このトピックについて読む価値のある投稿だけです

1
Kylo Ren

INotifyPropertyChangedで私が目にする主な問題は、viewmodelが多くのネストされたタイプを含む複雑な場合、階層全体でPropertyChangedイベントをバブルアップする必要があるように見えることです。

1
Ia McInnes