Datagrid性能非常低,即使使用UI虚拟化也是如此

时间:2011-05-20 07:36:57

标签: wpf performance datagrid datatemplate datagridtemplatecolumn

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

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

它运行良好,但如果我使用DataGridTemplateColumn s(因为我需要一个带有分隔符和2个标题的样式列标题,因为我需要每列2个子列)和单元格模板(仍然因为我需要这两个子列),它有一个双重绑定(每个子列一个绑定),当我加载网格时,它只是无法使用...

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

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

我甚至尝试使用自己的ListView / GridView,并在处理了几个小时后(为了复制冻结的列等等)。仍然存在相同的“问题”。

不可能使用Data Virtualization(因为“只有”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<string, MyCell> MyObject { get; set; } MyCell类具有FirstBinding和SecondBinding属性(字符串)。

1 个答案:

答案 0 :(得分:-1)

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

使用WPF大小计算得出问题(bug?)。我在RowDefinition Height =“Auto”的网格中得到它,这导致渲染系统尝试通过测量每个列和行的大小来尝试重新计算DataGrid的大小,可能是通过填充整个网格(据我所知)。它应该以某种方式智能地处理它,但在这种情况下它不是。

快速检查以确定这是否是一个相关问题是在测试期间将DataGrid的高度和宽度属性设置为固定大小,然后再次尝试运行。如果您的性能已恢复,则可以在以下选项中进行永久性修复:

  • 将包含元素的大小更改为相对(*)或 固定值
  • 将DataGrid的MaxHeight和MaxWidth设置为更大的固定值 比在正常使用中可以得到的
  • 尝试另一种具有不同调整大小策略的容器类型(Grid,DockPanel等)