我在這裏有一點點(沒有雙關語意圖);我有大量視圖模型(500+),它們使用ItemsControl
和WrapPanel
作爲ItemsPanelTemplate
顯示。這些視圖模型中的每一個都顯示Boolean?
,其值在用戶界面上綁定到CheckBox
的IsChecked
屬性。複選框綁定慢
問題是這樣的...每當我嘗試立即更新所有複選框時,它的速度非常慢。幾乎10秒鐘來更新500個項目的列表。如果我在一個單獨的線程中運行更新代碼,我幾乎可以看到複選框被逐一更新。
任何人都可以啓發我爲什麼這個過程如此緩慢,我如何能夠改善它?
我曾考慮過WrapPanel
的非虛擬化性質可能是罪惡派對。但是,當我綁定到IsEnabled
屬性而不是IsChecked
時,我看到一個有趣的結果;即將IsEnabled
的值更改爲true的速度與預期的一樣緩慢,但瞬時發生更改爲false的情況。這讓我懷疑複選框動畫是有問題的,因爲據我可以直觀地看到,在禁用複選框時沒有動畫,但是啓用時有。分析顯示絕大多數時間都花在PropertyChangedEventManager.OnPropertyChanged()
方法中。
示例代碼,我很遺憾不得不使用.NET 3.5:
XAML:
<ItemsControl ItemsSource="{Binding ChildItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.Resources>
<DataTemplate DataType="{x:Type SampleViewModel}">
<CheckBox IsThreeState="True" IsChecked="{Binding Path=IncludeInPrinting, Mode=OneWay}" />
</DataTemplate>
</ItemsControl.Resources>
</ItemsControl>
視圖模型:
public class SampleViewModel : INotifyPropertyChanged
{
private Boolean? _includeInPrinting;
public Boolean? IncludeInPrinting
{
get
{
return _includeInPrinting;
}
set
{
if (_includeInPrinting != value)
{
_includeInPrinting = value;
RaisePropertyChanged(() => IncludeInPrinting);
}
}
}
}
慢代碼:
foreach (SampleViewModel model in ChildItems)
{
model.IncludeInPrinting = false;
}
編輯:對於我t的價值每當我全選或取消選中所有複選框時,我也會看到內存使用率激增。 〜10MB
編輯:下面的性能分析似乎證實動畫確實是問題。
您可以嘗試的是禁用所有項目上的屬性通知,更改所有屬性,然後在持有所有項目的集合上引發NotifyCollectionChangedAction.Reset。 – dowhilefor
http://virtualwrappanel.codeplex.com/ – Bas
@dowhilefor原諒我的無知,但我如何提高'ObservableCollection'上的'NotifyCollectionChangedAction.Reset'? –