gpt4 book ai didi

c# - 在启用行虚拟化的情况下,如何停止在 WPF DataGrid 中滚动时调整列的大小?

转载 作者:行者123 更新时间:2023-12-04 17:53:39 25 4
gpt4 key购买 nike

我有一个 WPF DataGrid , 绑定(bind)到 DataTable其中可能包含可变数量的列。这DataTable可以在运行时更改其模式和数据,只要用户选择一个新的数据文件加载到应用程序中(在下面的示例中,这是通过单击加载数据按钮模拟的)。

我已将列宽设置为 Auto以便列自动调整大小以适合其标题文本或列中最长的行内容(以较大者为准)。这是我示例中的 MainWindow.xaml:

<Window x:Class="analog.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:analog"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button x:Name="loadData" Grid.Row="0" Margin="0" Content="Load Data" Click="loadData_Click" VerticalAlignment="Top" />
<DataGrid x:Name="dataGrid" Grid.Row="1" Margin="0" IsReadOnly="True" CanUserAddRows="False" ColumnWidth="Auto" SelectionUnit="Cell" />
</Grid>
</Window>

这里是 MainWindow.xaml.cs:

public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void loadData_Click(object sender, RoutedEventArgs e)
{
var data = new DataTable();
data.Columns.Add("A", typeof(string));
data.Columns.Add("B", typeof(string));
data.Columns.Add("C", typeof(string));

Enumerable.Range(1, 50).ToList().ForEach(i => {
var row = data.NewRow();
row["A"] = "aaa";
row["B"] = "bbb";
row["C"] = "ccc";
data.Rows.Add(row);
});

var longRow = data.NewRow();
longRow["A"] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
longRow["B"] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
longRow["C"] = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc";
data.Rows.Add(longRow);

dataGrid.ItemsSource = data.DefaultView;
}
}

这很完美,除了因为 DataGrid行是虚拟的(即滚动列表时按需呈现,而不是预先呈现),列只能自动调整大小以适应当前显示的内容。

但是,当您随后向下滚动到列表底部时,随着较长的单元格内容滚动到 View 中,列宽会突然发生显着变化,从而带来非常糟糕、令人迷惑的用户体验。

关闭行虚拟化不是一个选项(例如 EnableRowVirtualization="False" ),因为我正在加载一些大型数据集,如果没有它,性能会非常糟糕。

我了解使用虚拟化时在大小调整方面的限制,我对这种行为感到非常满意。如果列只保持最初呈现网格时设置的宽度,那是完全可以的,但我就是找不到办法做到这一点!

我已经尝试了一些相当可怕的 hack,包括这个我在初始渲染后循环遍历列并以编程方式将宽度(以像素为单位)设置为它们当前呈现的任何大小:

foreach (DataGridColumn column in dataGrid.Columns)
{
column.Width = new DataGridLength(column.ActualWidth, DataGridLengthUnitType.Pixel);
}

我目前正在手动调用它,方法是将它放在按钮单击处理程序中并在初始数据呈现后单击按钮 - 但这没有任何效果,并且当我降低到更长的值时仍然会调整大小.

那么,当我滚动 DataGrid 时如何停止调整列的大小? ?

最佳答案

另一个选项(不完全是问题的解决方案,但类似的情况,尤其是当 EnableColumnVirtualization 为真时)是简单地设置列的 MaxWidth 属性。一个例子:

public MainWindow()
{
InitializeComponent();

DataTable tab = new DataTable();
for (int i = 0; i < 1000; i++)
tab.Columns.Add("A" + i.ToString());
for (int i = 0; i < 1000; i++)
{
DataRow r = tab.NewRow();
for (int j = 0; j < 1000; j++)
r[j] = "something " + (i * i * j * j).ToString();
tab.Rows.Add(r);
}

DataGrid dg = new DataGrid() { EnableColumnVirtualization = true, EnableRowVirtualization = true };
this.Content = dg;
dg.ItemsSource = tab.AsDataView();
dg.AutoGeneratingColumn += Dg_AutoGeneratingColumn;
}

private void Dg_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
e.Column.MaxWidth = 100;
}

关于c# - 在启用行虚拟化的情况下,如何停止在 WPF DataGrid 中滚动时调整列的大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42256067/

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