95
votes

I have 3 columns in my DataGridView. What I am trying to do is have the first 2 columns auto fit to the width of the content, and have the 3rd column fill the remaining space.

Is it possible to do in WinForms? I am loading my data from an EF DataContext if that's any use. I have included an image of how it currently looks.

enter image description here

10

10 Answers

181
votes

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.

24
votes

This is my favorite approach...

_dataGrid.DataBindingComplete += (o, _) =>
    {
        var dataGridView = o as DataGridView;
        if (dataGridView != null)
        {
           dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
           dataGridView.Columns[dataGridView.ColumnCount-1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
        }
    };
15
votes

Just change Property from property of control: AutoSizeColumnsMode:Fill

OR By code

dataGridView1.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.Fill;

4
votes

Not tested but you can give a try. Tested and working. I hope you can play with AutoSizeMode of DataGridViewColum to achieve what you need.

Try setting

dataGridView1.DataSource = yourdatasource;<--set datasource before you set AutoSizeMode

//Set the following properties after setting datasource
dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;

This should work

0
votes

Try doing,

 AutoSizeColumnMode = Fill;
0
votes
public static void Fill(DataGridView dgv2)
   {
        try
        {
            dgv = dgv2;
            foreach (DataGridViewColumn GridCol in dgv.Columns)
            {
                for (int j = 0; j < GridCol.DataGridView.ColumnCount; j++)
                {
                    GridCol.DataGridView.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
                    GridCol.DataGridView.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                    GridCol.DataGridView.Columns[j].FillWeight = 1;
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
0
votes

To build on AlfredBr's answer, if you hid some of your columns, you can use the following to auto-size all columns and then just have the last visible column fill the empty space:

myDgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
myDgv.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None).AutoSizeMode = 
    DataGridViewAutoSizeColumnMode.Fill;
0
votes

This is what I have done in order to get the column "first_name" fill the space when all the columns cannot do it.

When the grid goes to small the column "first_name" gets almost invisible (very thin) so I can set the DataGridViewAutoSizeColumnMode property to AllCells as the others visible columns. For performance issues it's important to set them to None before data binding it and set back to AllCells in the DataBindingComplete event handler of the grid. Hope it helps!

private void dataGridView1_Resize(object sender, EventArgs e)
{
    int ColumnsWidth = 0;
    foreach(DataGridViewColumn col in dataGridView1.Columns)
    {
        if (col.Visible) ColumnsWidth += col.Width;
    }
    if (ColumnsWidth <dataGridView1.Width)
    {
        dataGridView1.Columns["first_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
    }
    else if (dataGridView1.Columns["first_name"].Width < 10) 
    {
        dataGridView1.Columns["first_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
    }
}
-1
votes
public void setHeight(DataGridView src)
{
    src.Height= src.ColumnHeadersVisible ? src.ColumnHeadersHeight : 0 +   src.Rows.OfType<DataGridViewRow>().Where(row => row.Visible).Sum(row => row.Height);
}
-2
votes

Try this :

  DGV.AutoResizeColumns();
  DGV.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.AllCells;