ビューモデルでINotifyPropertyChanged.PropertyChanged
を起動する単純な.NETプロパティで十分な場合についてのガイダンスはありますか?それでは、いつ本格的な依存関係プロパティに移行したいですか?それとも、DPは主にビューを対象としていますか?
いくつかのアプローチがあります:
1。依存関係プロパティ
依存関係プロパティを使用している間、それは要素で最も意味があります-視覚的な外観を持つクラス(UIElement
s)。
長所:
短所:
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番目が最も可能性が高いです。
全体として、それはビジュアル対データです。
私の知る限り、DependencyProperty
は必要な場合にのみ必要です
等.
これらの機能は、通常のプロパティでは使用できません。
プロパティにバインディングを設定できるようにする場合は、DependencyProperty
が必要です。通常、これは作成したカスタムUIElement
s用です。人々がデータをあなたのUIElement
sにバインドできるようにしたいのです。
<local:MyUIElement MyProperty={Binding Path=SomethingToBindTo} />
これを行うには、MyPropertyが依存関係プロパティである必要があります
他の回答が依存関係プロパティをいつ作成するかについてすでに十分に述べているように。つまり.
- PropertyValueの継承
- プロパティにバインディングを使用する必要があります
- プロパティにアニメーションを使用する
これに関するもう1つの視点/質問は、「WPFアプリケーションでは、コントロールに依存関係プロパティを作成するのが理にかなっています。これは、高さ、幅、テキスト、コンテンツ、背景などのユーザー操作中に変更される可能性があるためですしかし、Behaviors Classes(非UIクラス)のような他のクラスはどうですか?これらのクラスのプロパティは依存関係プロパティである必要がありますか? "
ここでは、いくつかのルールセットを絶対的または強調することはしませんが、プロパティをDPとして作成する必要があります。デザインの観点から、プロパティがDPの場合、使用/バインドするのは常にデフォルトのWPF形式です。
- DPは、通常のCLRプロパティと比較して、変更の反映がはるかに高速で自然です。
- DPには、割り当てられた値を検証するための検証メカニズムと、値を元に戻すためのデフォルトの構造があります。
- DPには、プロパティの制限を制御するための強制値コールバックがあります。
- DPには、CLRプロパティとは異なり、メタデータが関連付けられています。
慣例として、ネストされたバインディングで多くの間違いを犯し、変更を発生させるのを見てきました。この種の障害は、変更自体を発生させる設計と互換性のDPの原因では発生しません。したがって、少し余分な構文を使用して、アプリケーションに柔軟性/パフォーマンス/使いやすさを追加します。だから、手頃な価格ならどこでもそれを選びましょう。
それでも、ViewModelクラス/その他のヘルパークラスについては確信が持てません。将来、説得力のある理由が見つかった場合は、回答を更新します。
INotifyPropertyChanged
で私が目にする主な問題は、viewmodelが多くのネストされたタイプを含む複雑な場合、階層全体でPropertyChanged
イベントをバブルアップする必要があるように見えることです。