How to Automatically Resize Columns in a Datagridview Control and Allow the User to Resize the Columns on That Same Grid

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

This trick works for me:

grd.DataSource = DT;

// Set your desired AutoSize Mode:
grd.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
grd.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

// Now that DataGridView has calculated it's Widths; we can now store each column Width values.
for (int i = 0; i <= grd.Columns.Count - 1; i++)
{
// Store Auto Sized Widths:
int colw = grd.Columns[i].Width;

// Remove AutoSizing:
grd.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;

// Set Width to calculated AutoSize value:
grd.Columns[i].Width = colw;
}

In the Code above:
You set the Columns AutoSize Property to whatever AutoSizeMode you need.
Then (Column by Column) you store each column Width value (from AutoSize value);
Disable the AutoSize Property and finally, set the Column Width to the Width value you previously stored.

DataGridView column auto adjust width and resizable

I finally find a way to do what I wanted.

The idea is to

  • let the dataGridView resize the columns itself to fit the content, and then
  • change theAutoSizeColumnMode and set the width with the value you just stored.

Here is the code:

dataGridView.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
int widthCol = dataGridView.Columns[i].Width;
dataGridView.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
dataGridView.Columns[i].Width = widthCol;

Hope this will help.

Resize DataGridView width to fit Columns

Execute the following code after the grid is loaded with data and the columns have been sized accordingly (assuming you're setting the columns' AutoSize property at runtime).

dataGridView1.Width =
dataGridView1.Columns.Cast<DataGridViewColumn>().Sum(x => x.Width)
+ (dataGridView1.RowHeadersVisible ? dataGridView1.RowHeadersWidth : 0) + 3;

What it's doing:

  • Totals up the widths of all columns (using LINQ),
  • Sees if the "row header" is visible and adds that width too, if it is,
  • Adds 3 more because without that the horizontal scrollbar kept showing up - possibly because of margin/padding around the grid, I'm not sure.

DataGridView AutoFit and Fill

You need to use the DataGridViewColumn.AutoSizeMode property.

You can use one of these values for column 0 and 1:

AllCells: The column width adjusts to fit the contents of all cells in
the column, including the header cell.


AllCellsExceptHeader: The column width adjusts to fit the contents of all cells in the column, excluding the header cell.

DisplayedCells: The column width adjusts to
fit the contents of all cells in the column that are in rows currently
displayed onscreen, including the header cell.


DisplayedCellsExceptHeader: The column width adjusts to fit the
contents of all cells in the column that are in rows currently
displayed onscreen, excluding the header cell.

Then you use the Fill value for column 2

The column width adjusts so that the widths of all columns exactly fills the display area of the control...

this.DataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

As pointed out by other users, the default value can be set at datagridview level with DataGridView.AutoSizeColumnsMode property.

this.DataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;

could be:

this.DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;

Important note:

If your grid is bound to a datasource and columns are auto-generated (AutoGenerateColumns property set to True), you need to use the DataBindingComplete event to apply style AFTER columns have been created.


In some scenarios (change cells value by code for example), I had to call DataGridView1.AutoResizeColumns(); to refresh the grid.

Resizing DataGridView columns based on the grid width

How about:

  • You set the AutoSizeColumnsMode property to AllCellsExceptHeader, this would adjust all columns according to the values.

  • And, to your last column, you can set the style to Fill.

Also, checkout How to: Set the Sizing Modes of the Windows Forms DataGridView Control.

c# resize datagridview columns to fit control

private void dataGrid_SizeChanged(object sender, EventArgs e)
{
ResizeGridColumns();
}

private void ResizeGridColumns()
{
//get sum of non-resizable columns width
int diffWidth = 0;
foreach (DataGridViewColumn col in this.dataGrid.Columns)
{
if (col.Resizable == DataGridViewTriState.False && col.Visible) diffWidth += col.Width;
}

//calculate available width
int totalResizableWith = this.dataGrid.Width - diffWidth;

//resize column width based on previous proportions
this.dataGrid.ColumnWidthChanged -= new DataGridViewColumnEventHandler(dataGrid_ColumnWidthChanged);
for (int i = 0; i < this.colWidthRaport.Count; i++)
{
try
{
if (this.dataGrid.Columns[i].Resizable != DataGridViewTriState.False && this.dataGrid.Columns[i].Visible)
{
this.dataGrid.Columns[i].Width = (int)Math.Floor((decimal)totalResizableWith / this.colWidthRaport[i]);
}
}
catch { }
}
this.dataGrid.ColumnWidthChanged += new DataGridViewColumnEventHandler(dataGrid_ColumnWidthChanged);
}

private void dataGrid_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
CalculateGridColWidthsRaport();
}

/// <summary>Calculates the proportions between grid width and column width</summary>
private void CalculateGridColWidthsRaport()
{
//get sum of non-resizable columns width
int diffWidth = 0;
int colWidthsSum = 0;
foreach (DataGridViewColumn col in this.dataGrid.Columns)
{
if (col.Visible)
{
colWidthsSum += col.Width;
if (col.Resizable == DataGridViewTriState.False) diffWidth += col.Width;
}
}
colWidthsSum += 24;

//calculate available with
int totalResizableWith = colWidthsSum - diffWidth;// this.dataGrid.Width - diffWidth;
if (this.ParentForm.WindowState == FormWindowState.Maximized)
{
totalResizableWith = this.dataGrid.Width - diffWidth;
}

//calculate proportions of each column relative to the available width
this.colWidthRaport = new List<decimal>();
foreach (DataGridViewColumn col in this.dataGrid.Columns)
{
this.colWidthRaport.Add((decimal)totalResizableWith / (decimal)col.Width);
}
}


Related Topics



Leave a reply



Submit