ICollectionViewまたはObservableCollectionにバインドする必要があります


83

にバインドDataGridする必要があります

ICollectionView = CollectionViewSource.GetDefaultView(collection)

またはに

ObservableCollection<T> collection; ???

MVVMのベストプラクティスとその理由は何ですか?

回答:


129

あなたはいつもと結合するICollectionViewあなたはそれが明示か作りますか、。

私たちが持っていると仮定します

var collection = new ObservableCollection<string>();
var collectionView = CollectionViewSource.GetDefaultView(collection);

この場合、collectionまたはへのバインドcollectionViewは同じです。バインドエンジンは、にバインドするcollectionViewように指示すると、デフォルトのコレクションビュー(参照はに等しい)にバインドしcollectionます。

これは、あなたの質問に対する答えが「まったく違いがない」ということを意味します。

完全に明確にするために、コレクションに直接バインドする場合でも、バインドエンジンはデフォルトのビューにバインドします。並べ替え基準などのビューのプロパティを変更すると、コレクションに直接バインドされているように見えるバインドに影響します。これは、カバーの背後では、代わりにデフォルトビューへのバインドであるためです。

ただし、別の興味深い関連する質問があります。デフォルトのコレクションビュー(つまり、デフォルトビューに明示的にバインドする理由がないため、コレクション自体にバインドする必要があります)または同じコレクションの別のビューにバインドする必要がありますか?

各ビューには現在のアイテム、並べ替え基準などの独自の概念があることを考慮すると、同じコレクションに複数のバインディングを設定する場合、バインドされたコントロールには現在のアイテム、フィルター、会社の異なる概念を含める必要があります。必要なのは、同じ基になるコレクションの複数のビューに明示的にバインドすることです。


1
素晴らしい答え。私自身の好みは、ObservableCollectionがSystem.Collectionsの一部であり、ビューではなくモデルについて表現しているものをよりよく表すようになったため、ObservableCollectionにバインドすることですが、MVVMはこのように感じやすい場合があります。
Berryl 2011年

素晴らしい答え。Silverlightでは、バインドされたコレクションがICollectionViewFactoryを実装していない限り、バインドされたコレクションに対してデフォルトのCollectionViewが作成されないことを指摘しておきます。
jspaey 2012

これはユニバーサルアプリにも適用できますか?
ロバートマクリーン2014年

@RobertMacLean:WP開発の経験がないので、残念ながらわかりません。
ジョン

xamlで基になるコレクションの明示的なビューを作成するには、リソースでCollectionViewSource要素を作成します。CollectionViewSource.Sourceプロパティを基になるコレクションに結合します。次に、ItemsControl.ItemSourceプロパティを、StaticResourceを介してリソースに作成したCollectionViewSourceにバインドします。このように、1つのビューに適用された並べ替え/フィルター/グループ化操作は、デフォルトのCollectionViewにバインドされている他のItemsControlを「汚染」しません。
フランク劉

35

ObservableCollection<T>INotifyCollectionChangedコレクション内のアイテムが変更されたときにUIを実装し、通知します。

ICollectionViewINotifyCollectionChangedになるコレクションがそれを実装している場合、イベントの伝播に加えて、コレクションをフィルタリング、ソート、またはグループ化する機能を提供します。

どちらのタイプも、バインドしている限り、MVVMで適切に機能します。ICollectionView並べ替え、フィルタリング、またはグループ化が必要な場合に使用します。使用ObservableCollection<T>しない場合は直接使用してください。


この他の投稿は、ICollectionViewがコレクション変更イベントに基づいて自動的に更新されることと矛盾しているようです...それは正しくありませんか?stackoverflow.com/a/17906474/3195477
UuDdLrLrSs

@UuDdLrLrSsコレクション内のアイテムが変更された場合、それらのアイテムにバインドされているUI、またはそれらのアイテムのプロパティは、コレクションでRefreshを呼び出す必要なしに更新されます。もう1つの投稿では、コレクション内のアイテムのプロパティを変更し、ICollectionViewの更新を自動的にトリガーして、フィルター条件に一致するアイテムのみが含まれるようにすることについて具体的に質問しています。他の投稿の回答に基づいて、Refresh()メソッドを呼び出して、コレクション内のアイテムの「リスト」を更新する必要があります。
Jimmie R. Houts

9

ジョンが言ったことに追加するだけです。主な違いは、を使用CollectionViewSource.GetDefaultView(collection)することで、ViewModelをWPFに依存させることです。多くのMVVM純粋主義者はこれを嫌い、これはObservableCollectionのみを有効なオプションのままにします。

他のオプションはICollectionView、それを実装するクラスを使用して使用することですが、WPF自体の一部ではありません。


1
しかし、それは主な違いではありません。wpfタグに注意してください。「[if]バインドされたコントロールには、現在のアイテム、フィルター、および会社の明確な概念が必要です。必要なのは、同じ基になるコレクションの複数のビューに明示的にバインドすることです」。それが違いです。「純粋主義者」であることは、それが何であれ、フィルタリングなどができないことを意味します。より明確な言語の実際の違いに焦点を当てたジミーハウツの回答を参照してください。
ダークベスター2014

7

私はそうは思わないので、MVVMそれ自体とは何の関係もありません。ICollectionView必要に応じてグループ化などの追加機能を提供します。IColectionViewそれ以外の場合は単に使用します。ObservableCollection


2

グリッドにビューに適用された設定(フィルタリングなど)を表示する場合は、ビューにバインドします。それ以外の場合、ビューは冗長です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.