在數(shù)據(jù)量大的情況下,,DataGrid和ComboBox無法渲染或者渲染速度比較慢,。 首先我們來介紹下VirtualizingStackPanel 類(以下摘自MSDN) 標(biāo)準(zhǔn)布局系統(tǒng)可以創(chuàng)建項(xiàng)容器并為每個與列表控件關(guān)聯(lián)的項(xiàng)計算布局,。 “虛擬化”是指一種技術(shù),,通過該技術(shù),,可根據(jù)屏幕上所顯示的項(xiàng)來從大量數(shù)據(jù)項(xiàng)中生成用戶界面 (UI) 元素的子集。 如果在可能只有少量元素顯示在屏幕上時生成多個 UI 元素,,則會對應(yīng)用程序的性能產(chǎn)生負(fù)面影響,。 VirtualizingStackPanel 會計算可見項(xiàng)的數(shù)量,并處理來自 ItemsControl(如 ListBox 或 ListView)的 ItemContainerGenerator,,以便只為可見項(xiàng)創(chuàng)建 UI 元素。 僅當(dāng) StackPanel 中包含的項(xiàng)控件創(chuàng)建自己的項(xiàng)容器時,,才會在該面板中發(fā)生虛擬化,。 可以使用數(shù)據(jù)綁定來確保發(fā)生這一過程。 如果創(chuàng)建項(xiàng)容器并將其添加到項(xiàng)控件中,,則與 StackPanel 相比,,VirtualizingStackPanel 不能提供任何性能優(yōu)勢。 VirtualizingStackPanel 是 ListBox 元素的默認(rèn)項(xiàng)宿主,。 默認(rèn)情況下,,IsVirtualizing 屬性設(shè)置為 true。 當(dāng) IsVirtualizing 設(shè)置為 false 時,,VirtualizingStackPanel 的行為與普通 StackPanel 一樣,。 VirtualizingStackPanel.VirtualizationMode 附加屬性 VirtualizingStackPanel.VirtualizationMode 附加屬性指定 ItemsControl 中的面板如何虛擬化其子項(xiàng)。 默認(rèn)情況下,,VirtualizingStackPanel 將為每個可見項(xiàng)創(chuàng)建一個項(xiàng)容器,,并在不再需要時(比如當(dāng)項(xiàng)滾動到視圖之外時)丟棄該容器。 當(dāng) ItemsControl 包含多個項(xiàng)時,,創(chuàng)建和廢棄項(xiàng)容器的過程可能會對性能產(chǎn)生負(fù)面影響,。 如果 VirtualizingStackPanel.VirtualizationMode 設(shè)置為 Recycling,VirtualizingStackPanel 將重用項(xiàng)容器,,而不是每次都創(chuàng)建新的項(xiàng)容器,。 如果 VirtualizingStackPanel 無法回收項(xiàng)容器,它會使用標(biāo)準(zhǔn)虛擬化模式,,即為每個項(xiàng)創(chuàng)建和廢棄項(xiàng)容器,。 下面的列表描述了 VirtualizingStackPanel 無法回收項(xiàng)容器的幾種情況: ItemsControl 包含不同類型的項(xiàng)容器。 例如,,Menu 可能包含同時將 MenuItem 和 Separator 對象用作項(xiàng)容器的項(xiàng),。 可以顯式為 ItemsControl 創(chuàng)建項(xiàng)容器,。 有關(guān)顯式與隱式創(chuàng)建項(xiàng)容器的更多信息,請參見 ItemsControl 類,。 當(dāng) VirtualizingStackPanel 回收項(xiàng)容器時,,您可能需要保存與容器而不是與數(shù)據(jù)項(xiàng)本身關(guān)聯(lián)的狀態(tài)信息。 例如,,如果 Expander 控件中包含項(xiàng),,則 IsExpanded 狀態(tài)會綁定到項(xiàng)容器,而不是綁定到數(shù)據(jù)項(xiàng)本身,。 當(dāng) Expander 重復(fù)用于新項(xiàng)時,,IsExpanded 的當(dāng)前值也用于該新項(xiàng)。 此外,,舊項(xiàng)不保留其 IsExpanded 值,。 正文開始啦 在上面介紹中我們看到默認(rèn)情況下虛擬化是開啟的,并且虛擬化是只渲染可見部分的UI,。我用如下代碼做了個測試20列100行的數(shù)據(jù)DataGrid幾乎渲染不出來 <Grid x:Name="LayoutRoot" Background="White"> 我將代碼改成將DataGrid所在Row改成了“*” <Grid x:Name="LayoutRoot" Background="White"> DataGrid很快就渲染出來了,,我們得出結(jié)論當(dāng)高度為Auto的時候虛擬化被關(guān)閉,推測:虛擬化是渲染可見區(qū)域的UI,,當(dāng)控件為Auto的時候虛擬化將無法正常工作,。當(dāng)然在我的項(xiàng)目中很多地方都是高度自適應(yīng),虛擬化都被自動關(guān)閉了,。當(dāng)然只有在數(shù)據(jù)量比較大的情況下開啟虛擬化才有效果,,小數(shù)據(jù)事實(shí)上沒有效果。 我們可以試試在Auto的情況下將虛擬化強(qiáng)制開啟 <sdk:DataGrid Name="dataGrid" AutoGenerateColumns="True" 運(yùn)行后報錯:
事實(shí)上就是不報錯,,虛擬化也是很不起作用的,。
總結(jié):本文有點(diǎn)短(晚上有事要提前跑路啦),內(nèi)容有點(diǎn)少,。ComboxBox的虛擬化會加快打開下拉列表的速度,,還有ListBox等朋友們可以參見MSDN:http://msdn.microsoft.com/zh-cn/library/system.windows.controls.virtualizingstackpanel.aspx
本文來自張訓(xùn)博的博客,原文地址:http://www.cnblogs.com/ForrestZhang/archive/2011/02/22/1961375.html |
|