ObservableCollection
とBindingList
の違いを知りたいのは、Sourceでの追加/削除の変更を通知するために両方を使用したためですが、実際にどちらを優先するかはわかりません。
なぜ次のいずれかを選択するのですか?
ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();
または
BindingList<Employee> lstEmp = new BindingList<Employee>();
ObservableCollection
は、コレクションとまったく同じようにUIから更新できます。本当の違いはかなり簡単です:
ObservableCollection<T>
は、コレクションが変更されたときに通知を提供するINotifyCollectionChanged
を実装します(^^)ObservableCollection
が更新されると、バインディングエンジンがUIを更新できます。
ただし、BindingList<T>
はIBindingList
を実装します。
IBindingList
はコレクションの変更に関する通知を提供しますが、それだけではありません。 UIが使用できる機能の全体を提供し、変更に応じたUIの更新だけでなく、次のような多くの機能を提供します。
これらの機能はすべてObservableCollection<T>
で使用できません
もう1つの違いは、BindingList
は、アイテムがINotifyPropertyChanged
を実装するときにアイテム変更通知を中継することです。アイテムがPropertyChanged
イベントを発生させた場合、BindingList
はそれを受け取り、ListChangedType.ItemChanged
およびOldIndex=NewIndex
でListChangedEvent
を発生させます(アイテムが置き換えられた場合、OldIndex=-1
)。 ObservableCollection
はアイテム通知を中継しません。
Silverlightでは、BindingList
はオプションとして使用できません。ただし、ObservableCollection
sおよびICollectionView
(覚えている場合はIPagedCollectionView
)を使用できます。
実際の違いは、BindingListはWinForms用であり、ObservableCollectionはWPF用です。
WPFの観点から見ると、BindingListは適切にサポートされておらず、本当に必要な場合を除き、WPFプロジェクトで実際に使用することはありません。
もう1つObservableCollection
とBindingList
の大きな違いは便利で、トピックの入札決定要因になります。
BindingList
リスト変更ハンドラー:
ObservableCollection
コレクションの変更:
上記の簡単な説明:
BindingList
でアイテムのプロパティが変更された場合、ListChanged
イベントにより、 property(PropertyDescriptor)およびObservableCollection
はそれを提供しません。実際、ObservableCollection
は、アイテムで変更されたプロパティの変更イベントを発生させません。
上記の結論は、モデルクラスに実装されるINotifyPropertyChanged
に関するものです。デフォルトでは、アイテムのプロパティが変更された場合、changedイベントは発生しません。
含まれる要素に関する機能や変更通知などの最も重要な違いは、受け入れられた回答ですでに言及されていますが、言及する価値のあるものもあります。
パフォーマンス
AddNew
が呼び出されると、BindingList<T>
はIndexOf
ルックアップによって追加されたアイテムを検索します。 T
がINotifyPropertyChanged
を実装している場合、変更された要素のインデックスもIndexOf
によって検索されます(同じアイテムが繰り返し変更される限り、新しいルックアップはありません)。コレクションに数千の要素を格納する場合、ObservableCollection<T>
(またはO(1)ルックアップコストを使用したカスタムIBindingList
実装)がより望ましい場合があります。
完全性
IBindingList
インターフェイスは巨大なインターフェイスで(おそらく最もクリーンなデザインではありません)、実装者がその機能のサブセットのみを実装できるようにします。たとえば、AllowNew
、SupportsSorting
、およびSupportsSearching
プロパティは、AddNew
、ApplySort
、およびFind
メソッドをそれぞれ使用できるかどうかを示します。 BindingList<T>
自体がソートをサポートしていないことは、多くの場合人々を驚かせます。実際には、派生クラスに欠落している機能を追加させる仮想メソッドがいくつか用意されています。 DataView
クラスは、完全なIBindingList
実装の例です。ただし、そもそも型付きコレクション用ではありません。また、WinFormsのBindingSource
クラスはハイブリッドの例です。ソートをサポートする別のIBindingList
実装をラップする場合、ソートをサポートします。
ObservableCollection<T>
は既にINotifyCollectionChanged
インターフェイスの完全な実装です(単一のイベントのみがあります)。また、仮想メンバーもありますが、ObservableCollection<T>
は通常、その基本Collection<T>
クラスと同じ理由で派生します。バインディング機能を調整するのではなく、アイテムの追加/削除(データモデルコレクションなど)をカスタマイズします。
コピーとラッピング
ObservableCollection<T>
とBindingList<T>
の両方には、既存のリストを受け入れるコンストラクターがあります。別のコレクションによってインスタンス化された場合、それらは異なる動作をしますが:
BindingList<T>
は、提供されたリストのオブザーバブルwrapperとして機能し、BindingList<T>
で実行された変更は、基礎となるものに反映されますコレクションも。ObservableCollection<T>
は新しいList<T>
インスタンスをベースCollection<T>
コンストラクターに渡し、元のコレクションの要素をこの新しいリストにコピーします。もちろん、T
が参照型の場合、要素の変更は元のコレクションから表示されますが、コレクション自体は更新されません。