How do you automatically resize columns in a DataGridView control AND allow the user to resize the columns on that same grid?

后端 未结 24 2956
孤城傲影
孤城傲影 2020-11-29 18:03

I am populating a DataGridView control on a Windows Form (C# 2.0 not WPF).

My goal is to display a grid that neatly fills all available width with cells - i.e. no un

相关标签:
24条回答
  • 2020-11-29 18:45

    Slightly neater C# code from Miroslav Zadravec's code assuming all columns are to be autosized

    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;
    }
    
    0 讨论(0)
  • 2020-11-29 18:46
    • Thanks for the solution above (To iterate through the DataGridView.Columns, change AutoSizeMode to a valid one, collect width value and set it back after change AutoSizeMode to DataGridViewAutoSizeColumnMode.None).
    • I struggled with it, and noticed it won't work whenever it is called from the class constructor or any line before Form.Show() or Form.ShowDialog(). So I put this code snippet in the Form.Shown event and this works for me.
    • My transformed code, reguardless of whatever DataGridView.AutoSizeColumnsMode set before, I use DataGridViewColumn.GetPreferredWidth() instead of changing DataGridViewColumn.AutoSizeMode and set the width value immediately, then change DataGridView.AutoSizeColumnsMode once:

      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;
      }
      
    • Be sure to set

              dataGridView.AllowUserToResizeColumns = true;
      
    • I don't know how come this only works after the form is shown.

    0 讨论(0)
  • 2020-11-29 18:47
    foreach (DataGridViewColumn c in dataGridView.Columns)
        c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.AllCells, true);
    

    This should work whether the dataGridView has been displayed or not (i.e. even if called from the class constructor).

    The same method, but with DataGridViewAutoSizeColumnMode.DisplayedCells, fails in the above case for the obvious reason - no cell has been displayed yet! For some non-obvious reason, AutoResizeColumns also fails in this case.

    0 讨论(0)
  • 2020-11-29 18:48

    I had to do this in VB and prefer to split it out to a method that I placed in a Module. You can add the Fill column as another ByRef parameter if desired.

    ''' <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
    
    0 讨论(0)
  • 2020-11-29 18:49

    This autofits all columns according to their content, fills the remaining empty space by stretching a specified column and prevents the 'jumping' behaviour by setting the last column to fill for any future resizing.

    // 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;
    
    0 讨论(0)
  • 2020-11-29 18:49

    If you bind your datasource to a datatable for example, you need to set the properties after the binding is done:

            private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
            {
                dgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
                dgv.AutoResizeColumns();
                dgv.AllowUserToResizeColumns = true;
            }
    
    0 讨论(0)
提交回复
热议问题