優化效能:控制項
Windows Presentation Foundation (WPF) 包含許多在大部分 Windows 應用程式中使用的通用使用者介面 (UI) 元件。 本主題包含提升 UI 效能的技巧。
顯示大型資料集
和 ComboBox 之類的 ListView WPF 控制項可用來在應用程式中顯示專案清單。 如果要顯示的清單是大型清單,可能會影響應用程式的效能。 這是因為標準版面配置系統會建立與清單控制項相關聯之每個項目的版面配置容器,並計算其版面配置的大小和位置。 一般而言,您不需要同時顯示所有項目;而可以改為顯示子集,讓使用者自行捲動清單。 在此情況下,使用虛擬化 UI 就是合理的作法,這表示,系統會延後產生項目的項目容器和相關聯的版面配置計算,直到顯示項目為止。
UI 虛擬化是清單控制項的重要層面。 請不要將 UI 虛擬化和資料虛擬化混淆。 UI 虛擬化只會在記憶體中存放可見的項目;若為資料繫結案例,則會在記憶體中存放整個資料結構。 相反地,資料虛擬化只會在記憶體中存放螢幕上顯示的資料項目。
根據預設,當和控制項的清單專案系結至資料時,會啟用 ListView 和 ListBox 控制項的 UI 虛擬化。 TreeView 您可以將附加屬性設定 VirtualizingStackPanel.IsVirtualizing 為 true
來啟用虛擬化。 如果您想要針對衍生自 ItemsControl 的自訂控制項或使用 StackPanel 類別的現有專案控制項啟用 UI 虛擬化,例如 ComboBox ,您可以將 設定為 VirtualizingStackPanel ,並將 設定 ItemsPanelIsVirtualizing 為 true
。 不過,您可能會停用這些控制項的 UI 虛擬化而不自知。 以下是停用 UI 虛擬化的條件清單。
專案容器會直接新增至 ItemsControl 。 例如,如果應用程式明確將物件加入 ListBoxItem 至 ListBox , ListBox 則 不會虛擬化 ListBoxItem 物件。
中的 ItemsControl 專案容器是不同類型的。 例如, Menu 使用 Separator 物件的 無法實作專案回收,因為 Menu 包含 型 Separator 別和 MenuItem 的物件。
將 設定 CanContentScroll 為
false
。將 設定 IsVirtualizing 為
false
。
在虛擬化項目容器時,也應該考量是否具有與項目所屬之項目容器相關聯的其他狀態資訊。 在這種情況下,您必須將其他狀態儲存起來。 例如,您可能有控制項中包含的 Expander 專案,且 IsExpanded 狀態會系結至專案的容器,而不是專案本身。 當容器重複使用給新專案時,目前的 值 IsExpanded 會用於新專案。 此外,舊專案會遺失正確的 IsExpanded 值。
目前,WPF 控制項皆未內建支援資料虛擬化。
容器回收
.NET Framework 3.5 SP1 中新增的 UI 虛擬化優化,適用于繼承自 ItemsControl 的控制項是 容器回收, 也可以改善捲動效能。 ItemsControl填入使用 UI 虛擬化的 時,它會為每個捲動至檢視的專案建立專案容器,並終結從檢視中捲動的每個專案的專案容器。 容器回收 可讓控制項針對不同的資料項目重複使用現有的專案容器,如此一來,當使用者捲動 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 的效能。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應