パフォーマンスの最適化:データバインディングは、さまざまなアイテムソースのパフォーマンスへの影響など、データバインディングの解決方法に関する背景情報を提供します。「 ItemsSourceへのバインド」セクションを見てください。
リストボックスに表示する従業員のリストを保持するCLRリストオブジェクトがあるシナリオを考えてみます。これら2つのオブジェクト間の対応を作成するには、従業員リストをListBoxのItemsSourceプロパティにバインドします。ただし、新しい従業員がグループに参加しているとします。この新しい人物をバインドされたListBox値に挿入するには、この人物を従業員リストに追加するだけで、この変更がデータバインディングエンジンによって自動的に認識されることを期待できます。
その仮定は誤りであることがわかります。実際には、変更はリストボックスに自動的に反映されません。これは、CLRリストオブジェクトがコレクション変更イベントを自動的に発生させないためです。ListBoxに変更を反映させるには、従業員のリストを再作成し、それをListBoxのItemsSourceプロパティに再アタッチする必要があります。このソリューションは機能しますが、パフォーマンスに大きな影響を与えます。ListBoxのItemsSourceを新しいオブジェクトに再割り当てするたびに、ListBoxは最初に前のアイテムを破棄し、リスト全体を再生成します。ListBoxが複雑なDataTemplateにマップされている場合、パフォーマンスへの影響はさらに大きくなります。
この問題に対する非常に効率的な解決策は、従業員リストをObservableCollectionにすることです。ObservableCollectionオブジェクトは、データバインディングエンジンが受信できる変更通知を生成します。このイベントは、リスト全体を再生成することなく、ItemsControlからアイテムを追加または削除します。
1アイテムの更新時間(ミリ秒)
- CLRリストオブジェクトへ=1656ミリ秒
- ObservableCollectionへ=20ミリ秒
WPFがコレクションに直接バインドすることはありません。コレクションをバインディングソースとして指定すると、WPFは実際にはコレクションの既定のビューにバインドします。
コレクションビューは、バインドされたソースコレクションの上にあるレイヤーであり、基になるソースコレクション自体を変更することなく、並べ替え、フィルター、およびグループクエリに基づいてソースコレクションをナビゲートおよび表示できます。コレクションビューは、コレクション内の現在のアイテムへのポインターも保持します。ソースコレクションがINotifyCollectionChangedインターフェイスを実装している場合、CollectionChangedイベントによって発生した変更はビューに伝播されます。