如何自动调整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);