【问题标题】:Datagrid very low performance, even with UI VirtualizationDatagrid 的性能非常低,即使使用 UI 虚拟化也是如此
【发布时间】:2011-05-20 07:36:57
【问题描述】:

我目前正在使用 DataGrid。 大约 24 列是在 C# 中动态创建的。

我的 DataGrid 中总是有大约 300 个条目(由于一个条目代表一个“标题”,我无法创建分页系统,因为我必须在同一个页面中获取所有数据)。

效果很好,但是如果我使用DataGridTemplateColumns(因为我需要一个样式化的列标题,它有一个分隔符和 2 个标题,因为我需要每列上有 2 个子列)和单元格模板(仍然因为我需要这些2 个子列),它具有双重绑定(每个子列一个绑定),当我加载 Grid 时,它只是无法使用...

我尝试了所有类型的虚拟化(StackPanel、RowVirtualization、ColumnVirtualization 以及所有不同类型的值组合)。 我可以获得的“最佳”性能是将 RowVirtualization 和 ColumnVirtualization 设置为 True。

它现在“可用”,但是当我进行水平滚动时仍然很慢(即使我使用 FrozenColumn 后出现了一点图形错误......)

我什至尝试使用自己的 ListView / GridView,但在工作了几个小时后(为了重现冻结的列等...)仍然存在相同的“问题”。

无法使用数据虚拟化(因为“只有”24 列和 285 行,所以对用户来说根本不友好)。

谢谢!

编辑 1:这是生成列的代码

        ColumnCollection = new ObservableCollection<DataGridColumn>();
        DataGridTemplateColumn firstDtc_l = new DataGridTemplateColumn();
        firstDtc_l.Header = "Titles";
        FrameworkElementFactory spFactory_l = new FrameworkElementFactory(typeof(Grid));
        ColumnCollection.Add(firstDtc_l);
        int i = 0;

        foreach (string s in DynamicColumns)
        {
            DataGridTemplateColumn dtc_l = new DataGridTemplateColumn();
            Binding bindColor = new Binding();
            bindColor.Converter = new ChangedColorConverter();
            bindColor.ConverterParameter = "Column" + i;

            //DataTemplate
            DataTemplate dt_l = new DataTemplate("MyObject");
            spFactory_l = new FrameworkElementFactory(typeof(Grid));
            spFactory_l.Name = "CellTemplate";
            FrameworkElementFactory columnDefinition1 = new FrameworkElementFactory(typeof(ColumnDefinition));
            FrameworkElementFactory columnDefinition2 = new FrameworkElementFactory(typeof(ColumnDefinition));
            FrameworkElementFactory border1 = new FrameworkElementFactory(typeof(Border));
            border1.SetValue(Grid.ColumnProperty, 0);
            border1.SetValue(Border.BorderBrushProperty, Brushes.Gray);
            border1.SetValue(Border.BorderThicknessProperty, new Thickness(0,0,0,0));
            FrameworkElementFactory border2 = new FrameworkElementFactory(typeof(Border));
            border2.SetValue(Grid.ColumnProperty, 1);
            border2.SetValue(Border.BorderBrushProperty, Brushes.Gray);
            border2.SetValue(Border.BorderThicknessProperty, new Thickness(1, 0, 0, 0));
            FrameworkElementFactory textBlock1 = new FrameworkElementFactory(typeof(TextBlock));
            textBlock1.SetValue(Grid.ColumnProperty, 0);
            textBlock1.SetValue(TextBlock.ForegroundProperty, bindColor);
            Binding firstBind = new Binding("MyObject[Column"+i+"].FirstBinding");
            textBlock1.SetValue(TextBlock.TextProperty, localBind);
            FrameworkElementFactory textBlock2 = new FrameworkElementFactory(typeof(TextBlock));
            Binding secongBind = new Binding("MyObject[Column" + i + "].SecondBinding");
            textBlock2.SetValue(Grid.ColumnProperty, 0);
            textBlock2.SetValue(TextBlock.TextProperty, firstBind) 
            textBlock2.SetValue(TextBlock.ForegroundProperty, secongBind);
            border1.AppendChild(textBlock1);
            border2.AppendChild(textBlock2);

            spFactory_l.AppendChild(columnDefinition1);
            spFactory_l.AppendChild(columnDefinition2);
            spFactory_l.AppendChild(border1);
            spFactory_l.AppendChild(border2);
            dt_l.VisualTree = spFactory_l;

            dtc_l.Width = DataGridLength.Auto;
            dtc_l.CellTemplate = dt_l;
            dtc_l.Header = s;
            ColumnCollection.Add(dtc_l);
            i++;
        }   

DataGrid 绑定到“TheObject”的集合。 TheObject 类有一个public Dictionary&lt;string, MyCell&gt; MyObject { get; set; } MyCell 类具有 FirstBinding 和 SecondBinding 属性(字符串)。

【问题讨论】:

  • 没有 DataGridTemplateColumn 的性能如何?也许您应该为此发布代码。
  • 我知道性能低下是因为 DataGridTemplaceColumns... 但我不能使用另一种类型的列,因为我必须有一个 Styled Header(不仅仅是一个字符串作为标题),并且单元格模板(每个单元格 2 个绑定):/
  • 您可以为 TemplateColumn 发布您的代码/xaml 吗?
  • 我编辑了我的帖子。请注意,我使用 DependencyProperty 将所有列加载到数据网格。在这种方法中,我为每一列应用 HeaderStyle
  • 我已经启动了您的示例,水平滚动并没有那么慢,它比垂直滚动快得多。但是我不知道冻结列是什么,所以我没有重现这个功能,这可能是我的结果不同的原因。

标签: wpf performance datagrid datatemplate datagridtemplatecolumn


【解决方案1】:

我在 DataGrid 中遇到了类似的问题,其中在调整窗口大小、列排序等之后需要几秒钟才能刷新,并且在执行此操作时锁定了窗口 UI(1000 行,5 列)。

这归结为 WPF 大小计算的问题(错误?)。我将它放在 RowDefinition Height="Auto" 的网格中,这导致渲染系统在运行时尝试通过测量每一列和每一行的大小来重新计算 DataGrid 的大小,大概是通过填充整个网格(据我了解)。它应该以某种方式智能地处理这个问题,但在这种情况下它不是。

快速检查这是否是相关问题是在测试期间将 DataGrid 的 Height 和 Width 属性设置为固定大小,然后再次尝试运行。如果您的性能得到恢复,则可以使用以下选项进行永久性修复:

  • 将包含元素的大小更改为相对 (*) 或 固定值
  • 将 DataGrid 的 MaxHeight 和 MaxWidth 设置为更大的固定值 比正常使用时更容易
  • 尝试使用不同大小调整策略(Grid、DockPanel 等)的其他容器类型

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    • 2014-08-02
    • 2019-12-04
    • 1970-01-01
    • 2012-07-03
    • 2018-02-02
    相关资源
    最近更新 更多