如何自动调整DataGridView控件中的列的大小,并允许用户调整同一网格上的列?
我在Windows窗体(C#2.0不是WPF)上填充DataGridView控件。
我的目标是显示一个整齐地用单元格填充所有可用宽度的网格 – 即在右侧没有未使用的(深灰色)区域,并根据其包含的数据适当地调整每一列的大小,还允许用户调整任何列的大小根据他们的喜好。
我试图通过设置每个列的AutoSizeMode为DataGridViewAutoSizeColumnMode.AllCells,除了我设置为DataGridViewAutoSizeColumnMode.Fill的列之一,以确保网格的整个区域整齐地填充数据。 (我不介意当用户试图调整这个列的大小时,它会弹回到确保水平空间总是被使用的大小。)
但是,正如我所提到的,一旦加载,我希望允许用户调整列的大小以适应自己的需求 – 为每个列设置这些AutoSizeMode值,然后用户无法再调整这些列的大小。
我已经尝试不设置允许resize的所有列的AutoSizeMode,但不根据单元格包含的数据设置初始大小。 加载数据后,将网格的AutoSizeMode更改回“Not Set”时,会出现相同的结果。
有没有我在这里丢失的设置,允许自动设置默认列宽和用户resize,或者有其他技术,我必须填充DataGridView控件时使用?
这个技巧适用于我:
grd.DataSource = DT; //set autosize mode grd.Columns(0).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; grd.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; grd.Columns(2).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; //datagrid has calculated it's widths so we can store them for (i = 0; i <= grd.Columns.Count - 1; i++) { //store autosized widths int colw = grd.Columns(i).Width; //remove autosizing grd.Columns(i).AutoSizeMode = DataGridViewAutoSizeColumnMode.None; //set width to calculated by autosize grd.Columns(i).Width = colw; }
这里发生的事情是,你设置自动调整到你需要的任何模式,然后逐列存储从自动计算得到的宽度,移除自动resize,并将宽度设置为你之前存储的值。
也许你可以打电话
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.Fill);
设置数据源后。 它将设置宽度并允许resize。
更多关于MSDN的DataGridView.AutoResizeColumns方法(DataGridViewAutoSizeColumnsMode) 。
AC#版本的Miroslav Zadravec的代码
for (int i = 0; i < dataGridView1.Columns.Count-1; i++) { dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; } dataGridView1.Columns[dataGridView1.Columns.Count - 1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; for (int i = 0; i < dataGridView1.Columns.Count; i++) { int colw = dataGridView1.Columns[i].Width; dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; dataGridView1.Columns[i].Width = colw; }
作为社区维基发布,以免淹没别人的声誉
在我的应用程序,我已经设置
grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; grid.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
另外,我已经设置了
grid.AllowUserToOrderColumns = true; grid.AllowUserToResizeColumns = true;
现在列宽可以改变,列可以由用户重新排列。 这对我来说很好。
也许这会为你工作。
那么,我做了这样的事情:
dgvReport.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; dgvReport.AutoResizeColumns(); dgvReport.AllowUserToResizeColumns = true; dgvReport.AllowUserToOrderColumns = true;
以特定的顺序。 列被resize(扩展),用户可以在之后调整列大小。
如果我正确地理解了这个问题,应该有一个更简单的方法来完成你所需要的。 调用dgvSomeDataGrid.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
这应该够了吧。 但是,有一个陷阱,因为填充DataGridView控件后无法直接调用此方法。 相反,您将不得不为VisibleChanged事件添加一个EventHandler,并在其中调用该方法。
将数据添加到网格后,添加以下代码,根据每个单元格中的数据长度调整列
dataGrid1.AutoResizeColumns(); dataGrid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
这是结果
问题简历:
具有列宽适应内容(跨列不同的方法),
但是然后允许用户设置列的宽度…
从Miroslav Zadravec的回答开发 ,对我来说,立即使用自动计算column.Width
设置… column.Width
!
foreach (DataGridViewColumn column in dataGridView.Columns) { if (/*It's not your special column*/) { column.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; column.Width = column.Width; //This is important, otherwise the following line will nullify your previous command column.AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet; } } //Now do the same using Fill instead of AllCells for your special column
这已经过testing,当DataGridView
已经被创build,使用这样的技巧。
来自Miroslav Zadravec的代码略微整洁的C#代码假设所有列都将被自动化
for (int i = 0; i < dgvProblems.Columns.Count; i++) { dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; int colw = dgvProblems.Columns[i].Width; dgvProblems.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; dgvProblems.Columns[i].Width = colw; }
这将根据其内容自动调整所有列,通过拉伸指定的列来填充剩余的空白空间,并通过将最后一列设置为将来resize来防止“跳跃”行为。
// autosize all columns according to their content dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); // make column 1 (or whatever) fill the empty space dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; // remove column 1 autosizing to prevent 'jumping' behaviour dgv.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; // let the last column fill the empty space when the grid or any column is resized (more natural/expected behaviour) dgv.Columns.GetLastColumn(DataGridViewElementStates.None, DataGridViewElementStates.None).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
另一个版本的Miroslav Zadravec的代码,但稍微更自动化和通用:
public Form1() { InitializeComponent(); dataGridView1.DataSource = source; for (int i = 0; i < dataGridView1.Columns.Count - 1; i++) { dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; } dataGridView1.Columns[dataGridView1.Columns.Count].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } void Form1Shown(object sender, EventArgs e) { for ( int i = 0; i < dataGridView1.Columns.Count; i++ ) { int colw = dataGridView1.Columns[i].Width; dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; dataGridView1.Columns[i].Width = colw; } }
我把第二部分放到单独的事件中,因为我在表单的初始化中填充datagridvew
,如果两个部分都存在,则没有任何更改,因为可能autosize在显示datagridview
之后计算宽度,所以宽度在Form1()
方法中仍然是默认值。 完成这个方法之后,autosize会做一些技巧,之后立即(当表单显示时),我们可以通过代码的第二部分(这里是Form1Shown
事件)来设置宽度。 这对我来说就像一个魅力。
这里是一个简化的代码Miroslav Zadravec在C#中的答案:
CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader; for (int i = 0; i < dataGridView1.Columns.Count; i++) dataGridView1.Columns[i].Width = dataGridView1.Columns[i].Width; CurrentDGV.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
你有没有尝试设置DataGridViewColumns
对象的FillWeight
属性?
例如:
this.grid1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; this.grid1.Columns[0].FillWeight = 1.5;
我认为它应该适用于你的情况。
从Schnapple的版本稍微改进
int nLastColumn = dgv.Columns.Count - 1; for (int i = 0; i < dgv.Columns.Count; i++) { if (nLastColumn == i) { dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill; } else { dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; } } for (int i = 0; i < dgv.Columns.Count; i++) { int colw = dgv.Columns[i].Width; dgv.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None; dgv.Columns[i].Width = colw; }
dataGridView1.AutoResizeColumns();
列宽适合其内容我已经使用了下面的声明,它解决了我的问题。
第一步 :
RadGridViewName.AutoSize = true;
第二步 :
// This mode fit in the header text and column data for all visible rows. this.grdSpec.MasterTemplate.BestFitColumns();
第三步:
for (int i = 0; i < grdSpec.Columns.Count; i++) { // The column width adjusts to fit the contents all cells in the control. grdSpec.Columns[i].AutoSizeMode = BestFitColumnMode.AllCells; }
例如,如果将数据源绑定到数据表,则需要在绑定完成后设置属性:
private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e) { dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; dgv.AutoResizeColumns(); dgv.AllowUserToResizeColumns = true; }
- 感谢上面的解决scheme(要遍历
DataGridView.Columns
,将AutoSizeMode
更改为一个有效的,收集宽度值并更改AutoSizeMode
后更改为DataGridViewAutoSizeColumnMode.None
)。 - 我苦苦挣扎,并且注意到它在
Form.Show()
或Form.ShowDialog()
之前从类构造函数或任何行中调用时都不起作用。 所以我把这个代码片段放在Form.Shown
事件中,这对我Form.Shown
用。 -
我转换的代码,无论任何
DataGridView.AutoSizeColumnsMode
设置之前,我使用DataGridViewColumn.GetPreferredWidth()
而不是更改DataGridViewColumn.AutoSizeMode
并立即设置宽度值,然后更改DataGridView.AutoSizeColumnsMode
一次:private void form_Shown(object sender, EventArgs e) { foreach (DataGridViewColumn c in dataGridView.Columns) c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.DisplayedCells, true); dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None; }
-
一定要设置
dataGridView.AllowUserToResizeColumns = true;
-
我不知道这是怎么来的,只是在表格显示之后才起作用。
foreach (DataGridViewColumn c in dataGridView.Columns) c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);
无论dataGridView
是否已经显示(即使从类的构造函数中调用),这都应该起作用。
同样的方法,但与DataGridViewAutoSizeColumnMode.DisplayedCells
,在上述情况下,由于显而易见的原因失败 – 没有单元格已被显示! 由于某些不明显的原因, AutoResizeColumns
在这种情况下也失败。
我不得不在VB中这样做,而更愿意把它分解成一个我放在模块中的方法。 如果需要,可以将“填充”列添加为另一个ByRef参数。
''' <summary> ''' Makes all columns in a DataGridView autosize based on displayed cells, ''' while leaving the column widths user-adjustable. ''' </summary> ''' <param name="dgv">A DataGridView to adjust</param> Friend Sub MakeAdjustableAutoSizedGridCols(ByRef dgv As DataGridView) Dim width As Integer For Each col As DataGridViewColumn In dgv.Columns col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells width = col.Width col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None col.Width = width Next dgv.AllowUserToResizeColumns = True End Sub
这对我来说是奇迹:
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);