這篇博客將介紹WPF中的虛擬化技術(shù)。
1. Data Virtualization 通常情況下我們說(shuō)數(shù)據(jù)虛擬化是指數(shù)據(jù)源沒(méi)有完全加載,僅加載當(dāng)前需要顯示的數(shù)據(jù)呈現(xiàn)給用戶(hù)。這種場(chǎng)景會(huì)讓我們想到數(shù)據(jù)分頁(yè)顯示,當(dāng)需要特定頁(yè)面的數(shù)據(jù)時(shí),根據(jù)頁(yè)數(shù)請(qǐng)求相應(yīng)數(shù)據(jù)。
WPF沒(méi)有提供對(duì)Data Virtualization原生態(tài)的支持,當(dāng)時(shí)我們可以使用Paging相關(guān)技術(shù)來(lái)實(shí)現(xiàn)。在我先前的博客WPF 實(shí)現(xiàn) DataGrid/ListView 分頁(yè)控件中有介紹。
2. UI Virtualization 是針對(duì)數(shù)據(jù)容器渲染數(shù)據(jù)項(xiàng)的一個(gè)優(yōu)化。舉個(gè)例子,一個(gè)ListView/ListBox控件中有10000個(gè)Item,但是可見(jiàn)的只有10個(gè),那么此時(shí)只渲染并顯示這10個(gè)Item,剩余的9990個(gè)Item不實(shí)例化和顯示。這樣可以提高程序的性能。
WPF中VirtualizingStackPanel容器是實(shí)現(xiàn)了UI Virtualization的容器,VirtualizingStackPanel也是ListBox/ListView的默認(rèn)數(shù)據(jù)容器。
下面通過(guò)一個(gè)例子來(lái)展示開(kāi)啟UI 虛擬化和關(guān)閉UI 虛擬化對(duì)程序性能產(chǎn)生的影響。
<ListView x:Name="VirtualizationListView" VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsVirtualizing="True"/>
public MainWindow() { InitializeComponent(); this.Loaded += delegate { List<string> items = new List<string>(); for (int i = 0; i < 10000; i++) { items.Add(string.Concat("item", i)); } this.VirtualizationListView.ItemsSource = items; }; }
此時(shí)當(dāng)通過(guò)Scrollbar滾動(dòng)時(shí),內(nèi)存的波動(dòng)不明顯。
VirtualizingPanel.VirtualizationMode="Recycling"表示不循環(huán)實(shí)例化新的Item,例如Item1--Item20此時(shí)可見(jiàn),拖動(dòng)滾動(dòng)條到Item100,再?gòu)腎tem100返回至Item1--Item20時(shí),這時(shí)候Item1--Item20不會(huì)被重新實(shí)例化。默認(rèn)情況下 VirtualizingPanel.VirtualizationMode="Standard"。在ListView進(jìn)行滾動(dòng)時(shí),內(nèi)存會(huì)用增加。
當(dāng)關(guān)閉UI虛擬化之后,內(nèi)存的變化非常顯著,因?yàn)槌绦虺跏蓟瘯r(shí)就將這10000條數(shù)據(jù)全部在ListView中實(shí)例化出來(lái)了。
當(dāng)遇到上述場(chǎng)景時(shí),可以合理的使用虛擬化技術(shù)來(lái)提高程序的性能。
感謝您的閱讀。