2

基本的に、ここでは実際にどのように効率的か疑問に思います。

サンプルコード:

void GetItems()
{
    foreach (var item in items)
        myObservableCollection.Add(item);
}

これにより、毎回CollectionChangedイベントが発生し、UIが毎回更新される必要がありませんか?それとも、GetItems関数が完了するまで待機するようにしますか?

基本的に、WPFはそれを非常にうまく処理しているようですが、どうやってそれを行ったのだろうかと思います。

4

3 に答える 3

4

パフォーマンスの最適化:データバインディングは、さまざまなアイテムソースのパフォーマンスへの影響など、データバインディングの解決方法に関する背景情報を提供します。「 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イベントによって発生した変更はビューに伝播されます。

于 2011-10-03T15:17:08.993 に答える
3

イベントは変更のたびに発生します。

GUIは毎回反応して更新する必要はなく、それを延期することができます。
WinFormsがこれを最適化することはわかっていますが、WPFにも同様のアプローチがあると思います。

于 2011-10-03T15:01:56.683 に答える
0

UIが新しい結果を要求する頻度を確認したい場合は、それをパブリックプロパティとして公開し、myObservableCollectionのパブリックプロパティのget(アセッサー)にデバッグ行を配置します。

于 2011-10-03T15:27:48.147 に答える