Windows Presentation Foundation (WPF) には、ほとんどの Windows アプリケーションで使用される一般的なユーザー インターフェイス (UI) コンポーネントの多くが含まれています。 このトピックでは、UI のパフォーマンスを向上させる手法について説明します。
大きなデータ セットの表示
ListViewやComboBoxなどの WPF コントロールは、アプリケーション内の項目の一覧を表示するために使用されます。 表示するリストが大きい場合は、アプリケーションのパフォーマンスが影響を受ける可能性があります。 これは、標準レイアウト システムがリスト コントロールに関連付けられている各項目のレイアウト コンテナーを作成し、そのレイアウト サイズと位置を計算するためです。 通常、すべてのアイテムを同時に表示する必要はありません。代わりにサブセットを表示し、ユーザーが一覧をスクロールします。 この場合、UI 仮想化を使用することは理にかなっています。つまり、項目コンテナーの生成と項目に関連するレイアウト計算は、項目が表示されるまで延期されます。
UI 仮想化は、リスト コントロールの重要な側面です。 UI 仮想化は、データ仮想化と混同しないでください。 UI 仮想化では、表示される項目のみがメモリに格納されますが、データ バインディング シナリオでは、データ構造全体がメモリに格納されます。 これに対し、データ仮想化では、画面上に表示されるデータ項目のみがメモリに格納されます。
既定では、UI 仮想化は、リスト 項目がデータにバインドされるときに、 ListView コントロールと ListBox コントロールに対して有効になります。
TreeView 仮想化を有効にするには、 VirtualizingStackPanel.IsVirtualizing 添付プロパティを true
に設定します。
ComboBoxなどのStackPanel クラスを使用するItemsControlまたは既存の項目コントロールから派生するカスタム コントロールの UI 仮想化を有効にする場合は、ItemsPanelをVirtualizingStackPanelに設定し、IsVirtualizingをtrue
に設定できます。 残念ながら、これらのコントロールの UI 仮想化を実現せずに無効にすることができます。 UI 仮想化を無効にする条件の一覧を次に示します。
項目コンテナーは、 ItemsControlに直接追加されます。 たとえば、アプリケーションが明示的に ListBoxItem オブジェクトを ListBoxに追加した場合、 ListBox は ListBoxItem オブジェクトを仮想化しません。
ItemsControl内の項目コンテナーの種類は異なります。 たとえば、Separator オブジェクトを使用するMenuは、MenuにSeparator型とMenuItemのオブジェクトが含まれているため、項目のリサイクルを実装できません。
CanContentScrollを
false
に設定します。IsVirtualizingを
false
に設定します。
項目コンテナーを仮想化する際の重要な考慮事項は、項目に属する項目コンテナーに関連付けられている追加の状態情報があるかどうかです。 この場合は、追加の状態を保存する必要があります。 たとえば、 Expander コントロールに含まれる項目があり、 IsExpanded 状態が項目自体ではなく、項目のコンテナーにバインドされている場合があります。 コンテナーが新しい項目に再利用されると、 IsExpanded の現在の値が新しい項目に使用されます。 さらに、古い項目は正しい IsExpanded 値を失います。
現時点では、WPF コントロールはデータ仮想化の組み込みサポートを提供していません。
コンテナーのリサイクル
ItemsControlから継承するコントロールの .NET Framework 3.5 SP1 に追加された UI 仮想化の最適化は、コンテナーのリサイクルであり、スクロールパフォーマンスを向上させることもできます。 UI 仮想化を使用する ItemsControl がデータで満たされると、表示されるアイテムごとに項目コンテナーが作成され、表示外にスクロールする各項目の項目コンテナーが破棄されます。 コンテナーのリサイクル により、コントロールは既存の項目コンテナーを異なるデータ項目に再利用できるため、ユーザーが ItemsControlをスクロールする際に項目コンテナーが常に作成および破棄されないようにします。 VirtualizationMode添付プロパティをRecyclingに設定することで、アイテムのリサイクルを有効にすることができます。
仮想化をサポートする ItemsControl は、コンテナーのリサイクルを使用できます。 ListBoxでコンテナーのリサイクルを有効にする方法の例については、「ListBox のスクロール パフォーマンスの向上」を参照してください。
双方向仮想化のサポート
VirtualizingStackPanel は、水平方向または垂直方向に一方向に UI 仮想化をサポートする組み込みサポートを提供します。 コントロールに双方向仮想化を使用する場合は、 VirtualizingStackPanel クラスを拡張するカスタム パネルを実装する必要があります。 VirtualizingStackPanel クラスは、OnViewportSizeChanged、LineUp、PageUp、MouseWheelUpなどの仮想メソッドを公開します。これらの仮想メソッドを使用すると、リストの可視部分の変更を検出し、それに応じて処理することができます。
テンプレートの最適化
ビジュアル ツリーには、アプリケーション内のすべてのビジュアル要素が含まれています。 直接作成されたオブジェクトに加えて、テンプレート拡張によるオブジェクトも含まれます。 たとえば、 Buttonを作成すると、ビジュアル ツリーに ClassicBorderDecorator オブジェクトと ContentPresenter オブジェクトも取得されます。 コントロール テンプレートを最適化していない場合は、ビジュアル ツリーに余分な不要なオブジェクトを多数作成している可能性があります。 ビジュアル ツリーの詳細については、「 WPF グラフィックス レンダリングの概要」を参照してください。
後回しスクロール
既定では、ユーザーがスクロール バーのつまみをドラッグすると、コンテンツ ビューが継続的に更新されます。 コントロールのスクロールが遅い場合は、遅延スクロールの使用を検討してください。 遅延スクロールでは、ユーザーがサムを離したときにのみコンテンツが更新されます。
遅延スクロールを実装するには、 IsDeferredScrollingEnabled プロパティを true
に設定します。
IsDeferredScrollingEnabled は添付プロパティであり、 ScrollViewer およびそのコントロール テンプレートに ScrollViewer を持つ任意のコントロールで設定できます。
パフォーマンス機能を実装するコントロール
次の表に、データを表示するための一般的なコントロールと、パフォーマンス機能のサポートを示します。 これらの機能を有効にする方法については、前のセクションを参照してください。
コントロール | 仮想化 | コンテナーのリサイクル | 遅延スクロール |
---|---|---|---|
ComboBox | 有効にできる | 有効にできる | 有効にできる |
ContextMenu | 有効にできる | 有効にできる | 有効にできる |
DocumentViewer | 利用できません | 利用できません | 有効にできる |
ListBox | 既定値 | 有効にできる | 有効にできる |
ListView | 既定値 | 有効にできる | 有効にできる |
TreeView | 有効にできる | 有効にできる | 有効にできる |
ToolBar | 利用できません | 利用できません | 有効にできる |
注
TreeViewで仮想化とコンテナーのリサイクルを有効にする方法の例については、「TreeView のパフォーマンスの向上」を参照してください。
こちらも参照ください
- レイアウト
- レイアウトとデザイン
- データ バインディング
- コントロール
- スタイリングとテンプレート作成
- チュートリアル: WPF アプリケーション でのアプリケーション データのキャッシュ
.NET Desktop feedback