368

Model-View-ViewModel アーキテクチャの WPF アプリケーションで ViewModel を実装する場合、それをデータバインド可能にする方法として 2 つの主要な選択肢があるようです。DependencyPropertyビューがバインドするプロパティに使用する実装を見てきましたが、INotifyPropertyChanged代わりに ViewModel を実装しているのを見てきました。

私の質問は、いつどちらを優先すべきかということです。パフォーマンスの違いはありますか? ViewModel の依存関係を WPF に与えるのは本当に良い考えですか? 設計を決定する際に、他に何を考慮する必要がありますか?

4

14 に答える 14

221

Kentは、このトピックについて興味深いブログを書きました:モデルの表示:POCOとDependencyObjects

簡単な要約:

  1. DependencyObjectsはシリアル化可能としてマークされていません
  2. DependencyObjectクラスは、Equals()メソッドとGetHashCode()メソッドをオーバーライドしてシールします
  3. DependencyObjectにはスレッドアフィニティがあります–作成されたスレッドでのみアクセスできます

私はPOCOアプローチを好みます。INotifyPropertyChangedインターフェイスを実装するPresentationModel(別名ViewModel)の基本クラスは、http://compositeextensions.codeplex.comにあります。

于 2009-04-23T19:15:39.263 に答える
41

WPF パフォーマンス ガイドによると、DependencyObjects は、INotifyPropertyChanged を実装する POCO よりも確実に優れたパフォーマンスを発揮します。

http://msdn.microsoft.com/en-us/library/bb613546.aspx

于 2010-11-03T16:45:21.567 に答える
29

選択は、ビジネス ロジックと UI 抽象化レベルに完全に基づいています。適切な分離を望まない場合は、DP が適しています。

DependencyProperties は主に VisualElements レベルで適用されるため、ビジネス要件ごとに多くの DP を作成することはお勧めできません。また、INotifyPropertyChanged よりも DP の方がコストがかかります。WPF/Silverlight を設計するときは、UI と ViewModel を完全に分離して設計し、いつでもレイアウトと UI コントロールを変更できるようにしてください (テーマとスタイルに基づいて)。

この投稿も参照してください - https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel。このリンクには、この議論に非常に関連する Model-View-ViewModel パターンへの参照がたくさんあります。

于 2008-11-14T22:22:24.997 に答える
20

表現力の観点から、私は依存プロパティを使用することを十分に楽しんでおり、INotifyPropertyChanged. stringプロパティ名と、イベント サブスクリプションによるメモリ リークの可能性は別として、INotifyPropertyChangedより明示的なメカニズムがあります。

依存関係プロパティは、わかりやすい静的メタデータを使用して、「これを行うときは、これを行う」ことを意味します。これは、エレガンスに賛成票を投じる宣言型アプローチです。

于 2008-11-15T23:35:40.463 に答える
17

依存関係プロパティは、データバインディングへのソースとしてではなく、UI要素での(ターゲットとしての)バインディングをサポートすることを目的としています。これがINotifyPropertyの出番です。純粋な観点からは、ViewModelsでDPを使用しないでください。

「バインディングのソースになるために、プロパティは依存関係プロパティである必要はありません。バインディングソースとして任意のCLRプロパティを使用できます。ただし、バインディングのターゲットになるためには、プロパティは依存関係プロパティ。一方向または双方向のバインディングを有効にするには、ソースプロパティが、バインディングシステム、つまりターゲットに伝播する変更通知をサポートする必要があります。カスタムCLRバインディングソースの場合、これは、プロパティがINotifyPropertyChangedをサポートする必要があることを意味します。コレクションはINotifyCollectionChangedをサポートする必要があります。」

すべての依存関係オブジェクトをシリアル化することはできません(これにより、ViewModelsおよびDTO(POCO)の使用が妨げられる可能性があります。

Silverlight内のDPとWPFには違いがあります。

http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx

http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx

于 2011-11-09T10:07:49.730 に答える
15

INotifyPropertyChanged使用すると、ゲッターのコードとプロパティのセッターにロジックを追加することもできます。

DependencyProperty例:

public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );

public String Name
{
    set { SetValue( NameProperty, value ); }
    get { return ( String ) GetValue( NameProperty ); }
}

ゲッターとセッターでは---それぞれSetValueとGetValueを呼び出すだけです。フレームワークの他の部分では、ゲッター/セッターは呼び出されず、代わりにSetValue、GetValueを直接呼び出すため、プロパティロジックは呼び出されません。確実に実行されます。

を使用INotifyPropertyChangedして、イベントを定義します。

public event PropertyChangedEventHandler PropertyChanged;

次に、コード内の任意の場所にロジックを配置して、次のように呼び出します。

// ...
// Something cool...
// ...

if( this.PropertyChanged != null )
{
    PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}

// More cool stuff that will reliably happen...

これは、ゲッター/セッター、または他の場所にある可能性があります。

于 2009-02-13T19:18:19.077 に答える
7

ViewModel の依存関係を WPF に与えるのは本当に良い考えですか?

.NET 4.0 には System.Xaml.dll があるため、それを利用するために任意のフレームワークに依存する必要はありません。PDC セッションに関するRob Relyea の投稿を参照してください。

私の見解

XAML はオブジェクトを記述するための言語であり、WPF は記述されたオブジェクトが UI 要素であるフレームワークです。

それらの関係は、ロジックを記述するための言語である C# と、特定の種類のロジックを実装するフレームワークである .NET に似ています。

XAML の目的は、宣言型オブジェクト グラフです。W*F テクノロジはこのパラダイムの優れた候補ですが、XAML はそれらとは独立して存在します。

XAML と依存関係システム全体が WF と WPF の個別のスタックとして実装されたのは、おそらく、それらの間に依存関係を作成せずに異なるチームの経験を活用するためです (しゃれた意図はありません)。

于 2008-11-14T23:17:19.287 に答える
7

私も最近、この決定を検討しなければなりませんでした。

INotifyPropertyChanged メカニズムは、状態を複製することなく既存のビジネス ロジック フレームワークに GUI を接着できるため、私のニーズにより適していることがわかりました。私が使用していたフレームワークには独自のオブザーバー パターンがあり、あるレベルの通知を次のレベルに転送するのは簡単でした。ビジネス ロジック フレームワークからのオブザーバー インターフェイスと INotifyPropertyChanged インターフェイスを実装したクラスがあっただけです。

DP では、状態を格納するバックエンドを自分で定義することはできません。バインドしていた状態のすべてのアイテムのコピーを .net にキャッシュさせる必要がありました。これは不要なオーバーヘッドのように思えました。私の状態は大きくて複雑です。

ここで、ビジネス ロジックから GUI にプロパティを公開するには、INotifyPropertyChanged の方が優れていることがわかりました。

プロパティを公開するためにカスタム GUI ウィジェットが必要であり、そのプロパティへの変更が他の GUI ウィジェットに影響を与える必要がある場合、DP は単純なソリューションであることが証明されました。

それで、DPがGUIからGUIへの通知に役立つことがわかりました。

于 2008-11-24T17:16:32.707 に答える
6

依存関係プロパティは、カスタム コントロール作成の接着剤です。Intelli-sense を使用して、XAML の設計時にプロパティ ウィンドウにプロパティを表示することに関心がある場合は、依存関係プロパティを使用する必要があります。INPC は、設計時にプロパティ ウィンドウにプロパティを表示しません。

于 2014-10-28T21:04:28.717 に答える
4

ボタンなど、作成するコントロールでは依存関係プロパティを使用する必要があるようです。XAMLでプロパティを使用し、すべてのWPF機能を使用するには、それらのプロパティに依存関係プロパティが必要です。

ただし、ViewModelはINotifyPropertyChangedを使用する方が適切です。INotifyPropertyChangedを使用すると、必要に応じてゲッター/セッターロジックを使用できるようになります。

すでにINotifyPropertyChangedを実装しているViewModelの基本クラスのJoshSmithのバージョンを確認することをお勧めします。

http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/

これは、ViewModelを実行する方法の優れた例だと思います。

于 2009-03-25T01:59:11.477 に答える
4

DependencyProperty と INotifyPropertyChanged は Binding の 2 つの異なる目的で使用されると思います: 1 つ目は、プロパティをバインディングのターゲットにして、別のプロパティから入力を受け取ることを可能にするため ({Binding ...} を使用してプロパティを設定します)、最後はプロパティの値をバインディングのソースとして使用する場合 (バインディング パス式の名前)。したがって、選択は単に技術的なものです。

于 2010-09-02T18:37:07.253 に答える
3

a を好む理由は 1 つだけDependencyObjectです。バインディングの方がうまく機能します。ListBoxandを使用して例を試してみてください。TextBoxリストにINotifyPropertyChangedプロパティからのデータを入力し、DependencyProperty現在のアイテムを編集してくださいTextBox...

于 2011-03-27T20:18:30.787 に答える
3

INotifyPropertyChanged を使用しないプレゼンテーション モデルでブログを書いた、より直接的なアプローチを好みます。データ バインディングの代替手段を使用すると、ブックキーピング コードを使用せずに CLR プロパティに直接バインドできます。ビュー モデルに単純な古い .NET コードを記述するだけで、データ モデルが変更されると更新されます。

于 2008-12-30T13:15:14.593 に答える
0

プロパティを他のコントロールに公開したい場合は、依存関係プロパティを使用する必要があります...しかし、理解するのに時間がかかるので頑張ってください...

于 2011-02-03T21:05:21.793 に答える