Wpf Datagrid性能非常低,即使使用UI虚拟化

Wpf Datagrid性能非常低,即使使用UI虚拟化,wpf,performance,datagrid,datatemplate,datagridtemplatecolumn,Wpf,Performance,Datagrid,Datatemplate,Datagridtemplatecolumn,我目前正在使用DataGrid。 大约有24列是在C#中动态创建的 在我的DataGrid中总是有大约300个条目(因为一个条目代表一个“标题”,所以我不能创建分页系统,因为我必须在同一个页面中获取所有数据) 它工作得很好,但是如果我在加载网格时使用DataGridTemplateColumns(因为我需要一个样式化的列标题,它有一个分隔符和两个标题,因为我在每列上需要两个子列)和单元格模板(仍然是因为我需要这两个子列),它有一个双绑定(每个子列有一个绑定),它只是无法使用 我尝试了所有类型的虚

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

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

它工作得很好,但是如果我在加载网格时使用
DataGridTemplateColumn
s(因为我需要一个样式化的列标题,它有一个分隔符和两个标题,因为我在每列上需要两个子列)和单元格模板(仍然是因为我需要这两个子列),它有一个双绑定(每个子列有一个绑定),它只是无法使用

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

它现在是“可用的”,但当我水平滚动时仍然非常慢(即使有一点图形错误,因为我使用了冻结列…)

我甚至试着使用我自己的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++;
        }   
ColumnCollection=新的ObservableCollection();
DataGridTemplateColumn firstDtc_l=新DataGridTemplateColumn();
firstDtc_l.Header=“标题”;
FrameworkElementFactory spFactory_l=新FrameworkElementFactory(类型(网格));
ColumnCollection.Add(firstDtc_l);
int i=0;
foreach(DynamicColumns中的字符串s)
{
DataGridTemplateColumn dtc_l=新DataGridTemplateColumn();
Binding bindColor=新绑定();
bindColor.Converter=新更改的颜色转换器();
bindColor.ConverterParameter=“Column”+i;
//数据模板
DataTemplate dt_l=新的DataTemplate(“MyObject”);
spFactory_l=新的FrameworkElementFactory(类型(网格));
spFactory_l.Name=“CellTemplate”;
FrameworkElementFactory ColumnDefinition 1=新的FrameworkElementFactory(typeof(ColumnDefinition));
FrameworkElementFactory ColumnDefinition 2=新的FrameworkElementFactory(typeof(ColumnDefinition));
FrameworkElementFactory border1=新的FrameworkElementFactory(类型(边框));
border1.SetValue(Grid.ColumnProperty,0);
border1.SetValue(Border.BorderBrushProperty,Brush.Gray);
border1.SetValue(Border.BorderThicknessProperty,新厚度(0,0,0,0));
FrameworkElementFactory border2=新的FrameworkElementFactory(类型(边框));
border2.SetValue(Grid.ColumnProperty,1);
border2.SetValue(Border.BorderBrushProperty,Brush.Gray);
border2.SetValue(Border.BorderThicknessProperty,新厚度(1,0,0,0));
FrameworkElementFactory textBlock1=新FrameworkElementFactory(类型(TextBlock));
textBlock1.SetValue(Grid.ColumnProperty,0);
textBlock1.SetValue(TextBlock.ForegroundProperty,bindColor);
Binding firstBind=新绑定(“MyObject[列“+i+”].FirstBinding”);
textBlock1.SetValue(TextBlock.TextProperty,localBind);
FrameworkElementFactory textBlock2=新FrameworkElementFactory(类型(TextBlock));
绑定secongBind=新绑定(“MyObject[列“+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(列定义1);
spFactory_l.AppendChild(列定义2);
附加子对象(边界1);
附加子对象(边界2);
dt_l.VisualTree=spFactory_l;
dtc_l.Width=DataGridLength.Auto;
dtc_l.CellTemplate=dt_l;
dtc_l.标题=s;
ColumnCollection.Add(dtc_l);
i++;
}   
DataGrid绑定到“TheObject”的集合。 Object类有一个
公共字典MyObject{get;set;}

MyCell类具有FirstBinding和SecondBinding属性(字符串)。

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

这归结为WPF大小计算的一个问题(bug?)。我把它放在一个带有RowDefinition Height=“Auto”的网格中,这导致渲染系统在运行时通过测量每一列和每一行的大小来尝试重新计算DataGrid的大小,大概是通过填充整个网格(据我所知)。它应该以某种方式明智地处理这个问题,但在本例中,它不是

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

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

没有DataGridTemplateColumn,性能如何?也许你应该发布这方面的代码。我知道性能低下是因为DataGridTemplateColumns。。。但我不能再使用另一个