C# WPF DataGrid性能-过滤器性能
我们正处于将我们的应用程序从SilverLight转换为WPF的阶段,我们已经在这里开发了WPF 我们自己的自定义数据网格位于Silverlight的本地数据网格之上。应用程序由大量视图组成,其中 近99%的视图使用这些自定义网格 这是我们面临的最大挑战之一 与SilverLight相比,WPF版本应用程序中网格的性能。特别是过滤速度非常慢 我们已经创建了两个测试应用程序来比较和分析本机控件上的Silverlight和WPF。应用程序加载相同的数据集: 1000行混合数据-文本、bool、int和enum 绑定到混合数据的25列(5个相同的列重复5次) 从分析中,我们发现Silverlight datagrid似乎有一个特定的逻辑处理NotifyCollectionChanged.Reset事件(来自筛选的集合视图)。最终结果是整个过滤和布局操作在约700ms内完成 与此相反,WPF datagrid没有此逻辑,因此NotifyCollectionChanged.Reset被ItemCollection截获,而ItemCollection又截获了一个面板,该面板通过一个名为DegenantSwalker的类生成了一个嵌套非常深的调用树,其中包含大量递归调用。接下来是一个完整的更新周期。对于相同的过滤操作,WPF总共需要约3.7秒 是否有人经历过类似的迁移,您是否也经历过同样的问题?您是否找到了使用本机WPF datagrid的解决方案 数据如下所示。SilverLight和WPF的探查器(dotTrace)快照,以及所用源代码的摘录 SilverLight结果 WPF结果:C# WPF DataGrid性能-过滤器性能,c#,wpf,performance,grid,C#,Wpf,Performance,Grid,我们正处于将我们的应用程序从SilverLight转换为WPF的阶段,我们已经在这里开发了WPF 我们自己的自定义数据网格位于Silverlight的本地数据网格之上。应用程序由大量视图组成,其中 近99%的视图使用这些自定义网格 这是我们面临的最大挑战之一 与SilverLight相比,WPF版本应用程序中网格的性能。特别是过滤速度非常慢 我们已经创建了两个测试应用程序来比较和分析本机控件上的Silverlight和WPF。应用程序加载相同的数据集: 1000行混合数据-文本、bool、int
public class Data
{
private CollectionViewSource viewSource = new CollectionViewSource();
public Data()
{
var items = new List<Item>();
// Create 1000 items
viewSource.Source = items;
}
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>
1:使用深度嵌套的调用树进行筛选操作
2:更新更新周期
源代码:
public class Data
{
private CollectionViewSource viewSource = new CollectionViewSource();
public Data()
{
var items = new List<Item>();
// Create 1000 items
viewSource.Source = items;
}
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>
公共类数据
{
private CollectionViewSource viewSource=新的CollectionViewSource();
公共数据()
{
var items=新列表();
//创建1000个项目
viewSource.Source=项目;
}
public ICollectionView=>viewSource.View;
}
公共类项目
{
公共字符串说明{get;set;}=“Text here”;
公共bool bool{get;set;}
公共int值{get;set;}
公共日期时间时间戳{get;set;}
公共测试枚举值{get;set;}
公共静态IEnumerable AvailableEnumValues=>
Enum.GetValues(typeof(Test));
}