gpt4 book ai didi

c# - 在大型 wpf 数据网格中移动/隐藏列的性能问题

转载 作者:太空狗 更新时间:2023-10-29 17:59:40 25 4
gpt4 key购买 nike

我正在使用 wpf datagrid 来显示大量数据(大约 100 列和 1000 行)。这些列绑定(bind)到使用类型描述符动态添加的属性。默认情况下,数据网格显示所有列,但是我们添加了允许用户仅查看所有列的子集的功能,并且他们还可以更改显示列的顺序。我目前通过切换列的可见性属性并更改它们的显示索引来实现这一点。然而,这样做的性能真的很糟糕。

下面是重现问题的例子

XAML 看起来非常简单

<Window x:Class="WpfDataGridTestApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowState="Maximized">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Height="Auto" Margin="5">
<CheckBox x:Name="ApplyColumns" Width="200" Margin="5" Checked="CheckBox_Checked" Unchecked="CheckBox_Checked">Show Predefined Columns</CheckBox>
</StackPanel>
<DataGrid
x:Name="Grid" EnableColumnVirtualization="False"
EnableRowVirtualization="False"
Grid.Row="1" SelectionUnit="Cell"
ItemsSource="{Binding MyDataView}">
</DataGrid>
</Grid>

后面的代码如下

    public partial class MainWindow : Window
{
/// <summary>
/// this dictionary stores the column name of columns to display and their displayIndex
/// </summary>
Dictionary<string,int> _predefinedColumns=new Dictionary<string, int>()
{
{"Column_8",0},
{"Column_9",1},
{"Column_11",2},
{"Column_14",3},
{"Column_12",4},
{"Column_34",5},
{"Column_78",6},
{"Column_54",7},
{"Column_88",8},
{"Column_98",9},
{"Column_90",10},
{"Column_51",11},
{"Column_100",12},
{"Column_35",13},
{"Column_112",14},
{"Column_101",15}
};
public MainWindow()
{
InitializeComponent();
DataContext = new MyClassViewModel();
}

/// <summary>
/// Toggle display of only subset of columns
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CheckBox_Checked(object sender, RoutedEventArgs e)
{
if (ApplyColumns.IsChecked ?? false)
{
foreach (var col in this.Grid.Columns)
{
if (_predefinedColumns.ContainsKey(col.Header as string))
{
col.Visibility = Visibility.Visible;
col.DisplayIndex = _predefinedColumns[col.Header as string];
}
else
{
col.Visibility = Visibility.Collapsed;
}
}
}
else
{
foreach (var col in this.Grid.Columns)
{
col.Visibility = Visibility.Visible;
var header = col.Header.ToString();
col.DisplayIndex = Int32.Parse(header.Substring(7)) - 1;
}
}
}
}

此 View 模型使用手动创建的 DataTable 再现大数据。然而,在 datagrid 背后的实际代码中,使用 typedescripter 添加动态属性绑定(bind)到类

    public class MyClassViewModel
{
public DataView MyDataView
{
get
{
var dt = new DataTable();
foreach (var colNum in Enumerable.Range(1, 120))
{
dt.Columns.Add(String.Format("Column_{0}", colNum), Type.GetType("System.Int32"));
}

var r = new Random();
for (int x = 1; x <= 1000; x++)
{
var dr = dt.NewRow();
foreach (var colNum in Enumerable.Range(1, 120))
{
dr[String.Format("Column_{0}", colNum)] = r.Next(100);
}
dt.Rows.Add(dr);
}
return dt.DefaultView;
}
}
}

我尝试了以下方法,但到目前为止没有成功

1. 开启行列虚拟化性能会更好。然而,这会破坏滚动性能,这是 Not Acceptable (尤其是当您尝试拖动拇指时)。
2. 我没有更改显示和可见性,而是尝试删除所有列,然后仅添加所需的列,但这也没有影响性能。

我将非常感谢对此的任何帮助。我们不希望以不利的滚动性能为代价来提高性能。那么如果需要开启虚拟化,我们如何提高滚动性能。或者有任何更好的方法来实现良好的滚动性能和良好的列显示/隐藏/移动性能与如此大的数据网格。

最佳答案

当使用较大的数据集时,您确实应该启用虚拟化,否则每个单元格都会通过布局/测量 channel ,即使它没有在屏幕上呈现也是如此。我通过使用 ScrollViewer.IsDeferredScrollingEnabled="False"调整滚动行为取得了一些成功,但总的来说,在 WPF 数据网格中的大数据集的性能方面运气不佳。

关于c# - 在大型 wpf 数据网格中移动/隐藏列的性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8336836/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com