Resizing Data Grid Columns To Content


This article was contributed by
Tom Archer.

Environment: .NET, C#

Demo application to test datagrid resizing method

Introduction

One peculiar omission from the Windows Forms teams regarding the DataGrid object is a method that enables you to resize the grid’s columns to visually accomodate the width of its widest data value. This method gives you that ability.

Acknowledgements

While searching for a solution to this problem, a friend emailed me some Visual Basic.NET code to accomplish the feat. While I could not get the code to compile (I’m assuming it was written during one of the .NET betas), I did re-write it in C# and got it to work. I’ll update this article to give a proper acknowledgment once I track down the original author’s name. However, I did want to make clear that some kind soul did get me 90% of the way there with their VB code and I finished the rest for my C# environment.

Using the Code

Syntax

Calling this method is very straightforward. It takes only two parameters:

public void SizeColumnsToContent(DataGrid dataGrid,
                                 int nRowsToScan)
  • dataGrid—The DataGrid object to be resized
  • nRowsToScan—The number of rows to scan when searching for the widest value for a given column. Passing a value of -1 indicates that all rows should be scanned.

Notes

  • In my own code, I have defined a method as a member of my own System.Windows.Forms.DataGrid-derived class (DataGridEx). I removed it from that class for this article to keep things simple. To use the method in the same manner that I did, simply remove the dataGrid parameter from the parameter list and replace the references to dataGrid with reference to the this object.
  • The reason for the nRowsToScan parameter is for performance issues regarding very large amounts of data. If you happen to have a datagrid with a large number of rows, you can simply have the grid’s columns sized according to the widest column of the first n rows instead of the method iterating through the entire data set for each column.

SizeColumnsToContent Method

public void SizeColumnsToContent(DataGrid dataGrid,
       int nRowsToScan)
{
  // Create graphics object for measuring widths.
  Graphics Graphics = dataGrid.CreateGraphics();

  // Define new table style.
  DataGridTableStyle tableStyle = new DataGridTableStyle();

  try
  {
    DataTable dataTable = (DataTable)dataGrid.DataSource;

    if (-1 == nRowsToScan)
    {
      nRowsToScan = dataTable.Rows.Count;
    }
    else
    {
      // Can only scan rows if they exist.
      nRowsToScan = System.Math.Min(nRowsToScan,
                    dataTable.Rows.Count);
    }

    // Clear any existing table styles.
    dataGrid.TableStyles.Clear();

    // Use mapping name that is defined in the data source.
    tableStyle.MappingName = dataTable.TableName;

    // Now create the column styles within the table style.
    DataGridTextBoxColumn columnStyle;
    int iWidth;

    for (int iCurrCol = 0;
         iCurrCol < dataTable.Columns.Count; iCurrCol++)
    {
      DataColumn dataColumn = dataTable.Columns[iCurrCol];

      columnStyle = new DataGridTextBoxColumn();

      columnStyle.TextBox.Enabled = true;
      columnStyle.HeaderText = dataColumn.ColumnName;
      columnStyle.MappingName = dataColumn.ColumnName;

      // Set width to header text width.
      iWidth = (int)(Graphics.MeasureString
                    (columnStyle.HeaderText,
                     dataGrid.Font).Width);

      // Change width, if data width is
      // wider than header text width.
      // Check the width of the data in the first X rows.
      DataRow dataRow;
      for (int iRow = 0; iRow < nRowsToScan; iRow++)
      {
        dataRow = dataTable.Rows[iRow];

        if (null != dataRow[dataColumn.ColumnName])
        {
          int iColWidth = (int)(Graphics.MeasureString
                          (dataRow.ItemArray[iCurrCol].ToString(),
                           dataGrid.Font).Width);
          iWidth = (int)System.Math.Max(iWidth, iColWidth);
        }
      }
      columnStyle.Width = iWidth + 4;

      // Add the new column style to the table style.
      tableStyle.GridColumnStyles.Add(columnStyle);
    }
    // Add the new table style to the data grid.
    dataGrid.TableStyles.Add(tableStyle);
  }
  catch(Exception e)
  {
    MessageBox.Show(e.Message);
  }
  finally
  {
    Graphics.Dispose();
  }
}

Downloads

Download demo project – 35 Kb
Download source – 2 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read