65.9K
CodeProject is changing. Read more.
Home

Resizing Data Grid Columns To Content

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.87/5 (25 votes)

Mar 18, 2003

2 min read

viewsIcon

203589

downloadIcon

4016

Method that resizes all the columns of a specified Data Grid object

Sample Image - SizeColumnsToContent.jpg

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 this method as a member of my own System.Windows.Forms.DataGrid-derived class (DataGridEx). I removed it from that class for this article, in order 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();
    }
}

History

  • March 18, 2003 - First posting