我们正处于将Silverlight应用程序转换为WPF的阶段。不幸的是,我们发现在WPF中过滤DataGrid非常慢。
我们创建了两个测试应用程序,以比较和分析本机控件上的Silverlight和WPF。应用程序加载相同的数据集:
DataGrid已完全虚拟化,并且我们使用谓词进行过滤绑定到ICollectionView。 DataGrid已全部虚拟化:
public class Data
{
private CollectionViewSource viewSource = new CollectionViewSource();
public Data()
{
var items = new List<Item>();
// Creating 1000 Item here...
var source = new CollectionViewSource() { Source = Items };
View = source.View;
View.Filter = i => IsMatch(i as Item);
}
public ICollectionView View => viewSource.View;
}
public class Item
{
public string Description { get; set; } = "Text here";
public bool Bool { get; set; }
public int Value { get; set; }
public DateTime TimeStamp { get; set; }
public Test EnumValue { get; set; }
public static IEnumerable AvailableEnumValues => Enum.GetValues(typeof(Test));
}
<DataGrid ItemsSource="{Binding View}"
EnableColumnVirtualization="True" EnableRowVirtualization="True"
VirtualizingPanel.IsContainerVirtualizable="False"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
VirtualizingStackPanel.CacheLength="2,3"
VirtualizingStackPanel.CacheLengthUnit="Page"
VirtualizingStackPanel.ScrollUnit="Item">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Description}" Width="100"/>
<DataGridTextColumn Binding="{Binding Value}" Width="100"/>
<DataGridCheckBoxColumn Binding="{Binding Bool}" Width="100"/>
<DataGridComboBoxColumn SelectedItemBinding="{Binding EnumValue}" ItemsSource="{x:Static local:Item.AvailableEnumValues}" Width="100"/>
<DataGridTextColumn Binding="{Binding TimeStamp}" Width="100"/>
<!-- Repeat 5 columns above 5 times -->
</DataGrid.Columns>
</DataGrid>
使用手机上的秒表,我们得到以下结果 结果如下:
有人遇到过同样的问题,并且找到了加速过滤的方法吗?
通过分析,我们发现Silverlight数据网格似乎具有从集合视图处理NotifyCollectionChanged.Reset事件的特定逻辑。 “ DataGridConnection”将拦截事件并在DataGrid上调用RefreshRows。相反,WPF数据网格不具有此逻辑,因此NotifyCollectionChanged.Reset被ItemContainerGenerator拦截,这引发了ItemsChanged事件。这由面板处理,该面板通过称为DescendantsWalker的类清除所有子节点,这些子节点导致嵌套非常深的调用树,并带有许多递归调用。接下来是完整的UpdateLayout周期(度量和安排),大概遍历所有行和单元格。
我们已经将其与其他几个DataGrid提供程序进行了比较,其中一些确实比WPF表现出更好的 MUCH ,所以这绝对有可能。
下面是SL和WPF的探查器会话的快照,以及所用源代码的摘录。