我在这里有一点点(没有双关语意图);我有大量视图模型(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'? –