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 the
AutoSizeColumnMode
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 toAllCellsExceptHeader
, 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
Retrieving Files from Directory That Contains Large Amount of Files
Serializing/Deserializing with Memory Stream
Create/Use User-Defined Functions in System.Data.Sqlite
How to Multiple Insert Multiple Records
Wpf Error 40 Bindingexpression Path Error: Property Not Found on 'Object'
How to Use a Dataadapter with Stored Procedure and Parameter
Build Visual Studio Project Through the Command Line
Linq Aggregate and Group by Periods of Time
Is Async Httpclient from .Net 4.5 a Bad Choice for Intensive Load Applications
Azure Shared Access Signature - Signature Did Not Match
Are There Good Reasons Not to Use an Orm
Why Does Environment.Exit() Not Terminate the Program Any More
Visual Studio Designer in X64 Doesn't Work
Main: Not All Code Paths Return a Value
Format a Number with Commas and Decimals in C# (ASP.NET MVC3)
How to Determine the Length (I.E. Duration) of a .Wav File in C#