Resizing Data Grid Columns To Content


This article was contributed by Tom Archer.

Environment: .NET, C#



Click here for a larger image.

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


About the Author

Tom Archer - MSFT

I am a Program Manager and Content Strategist for the Microsoft MSDN Online team managing the Windows Vista and Visual C++ developer centers. Before being employed at Microsoft, I was awarded MVP status for the Visual C++ product. A 20+ year veteran of programming with various languages - C++, C, Assembler, RPG III/400, PL/I, etc. - I've also written many technical books (Inside C#, Extending MFC Applications with the .NET Framework, Visual C++.NET Bible, etc.) and 100+ online articles.

Comments

  • Thanks

    Posted by sohaib on 07/04/2012 03:15am

    thanks for uploading this thing, i got my dataTable properly shown in Gridview by using the above function in my WIN CE 6.0 Device. .Net framework 3.5 Sohaib

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • With the average hard drive now averaging one terabyte in size, the fallout from the explosion of user-created data has become an overwhelming volume of potential evidence that law-enforcement and corporate investigators spend countless hours examining. Join Us and SANS' Rob Lee for our 45-minute webinar, A Triage and Collection Strategy for Time-Sensitive Investigations, will demonstrate how to: Identify the folders and files that often contain key insights Reduce the time spent sifting through content by …

Most Popular Programming Stories

More for Developers

RSS Feeds