Search
Wednesday, August 20, 2008 ..:: Articles ::.. Register  Login
  
Auto size DataGrid columns and headers
by Sai Panyam Last Updated:18 Oct 2004 View Count:1241 Rating:( 0/ 9 ) from 1 Vote(s)
Summary

The default feature of a datagrid doesn't automatically size the columns to the maximum data length of its columns. We have to double click the column boundary to size it. This becomes annoying after some time. This sample demonstrates an implementation of auto sizing the entire grid, specific column or a range of columns.

Artifacts can be downloaded from here.
AutoSizeDataGridCols.zip (32 kb)
Auto Size Me!

To auto size a column we need to examine and measure the data lengths of each piece of data present at a particular row and column for the entire grid. We then take the maximum length of the data in each column and set the column’s width to this value.

On first pass this looks like a viable solution. But in one particular scenario where the width of Header Text of the column is longer than the maximum width of the column data, the header text appears squished and we are back to square one in terms of clicking the column boundary to resize it. So we need to measure the header text width in addition to the column data.

private void AutoSizeCol(int colIndex)

{

    DataTable tbl =dataGrid1.DataSource as DataTable;

     int rowCount =tbl.Rows.Count;

     if (0!=rowCount)

    {

        //Gets a new Graphics object from the handle of the datagrid window

         Graphics g =Graphics.FromHwnd(dataGrid1.Handle);

         StringFormat sf =new StringFormat(StringFormat.GenericTypographic);

         SizeF headerSize;

          string headerText=dataGrid1.TableStyles["Customers"].GridColumnStyles[colIndex].HeaderText;

          //the param value for maximum layout area is an approximation

          //You can play around with this if the grid is not autosizing correctly

          //That is you can increase it and see the effects

         headerSize=g.MeasureString(headerText,dataGrid1.Font,500,sf);

          //Check the sizes of the column data

         Single width=0;

         SizeF dataSize;

          for(int rowIndex=0;rowIndex<rowCount; rowIndex++)

         {

              string colData =dataGrid1[rowIndex,colIndex].ToString();

             dataSize=g.MeasureString(colData,dataGrid1.Font,500,sf);

              if(dataSize.Width >width)

             {

                 width=dataSize.Width;

             }

         }

//This is used for taking care of leading and trailing padding of the text field

//You can experiment with it to find the right padding factor for your tables.

           int paddingFactorHeader =10;

           int paddingFactorData=10;

 

           //f the width of the header is less than the Maximum Column Data width then use

           // Max Column Width

           //Else

           //Use the width of the column header

           if(headerSize.Width <width)

          {

             dataGrid1.TableStyles["Customers"].GridColumnStyles[colIndex].Width =Convert.ToInt32(width) + paddingFactorData;

          }

           else

          {

             dataGrid1.TableStyles["Customers"].GridColumnStyles[colIndex].Width=Convert.ToInt32(headerSize.Width) + paddingFactorHeader; 

           }

 

           g.Dispose(); //Release this resource

   }

}

In order to measure the width of a string, we need to get a reference to the Graphics object, which exposes a method called MeasureString that does the trick. To get to the graphics object for the grid we need to get the handle of the DataGrid window using the FromHwnd method of the Graphics class and pass the DataGrid’s Handle.

 

We first measure the width of header text once for each column and then compare this value with the maximum width of the column data. Finally we take the greater of these two widths and set the width of the column to this value.

 

Troubleshooting

It so happens that internally when the datagrid paints the text of the data, it is narrower than the width returned by the MeasureString method, so we need to add a ‘padding factor’ to our returned widths. This needs a trial and error method and a padding factor of 10 seems to work fine.

 

One of the parameters of the MeasureString method that we need to pass is the maximum layout size (SizeF structure). This determines the maximum layout area of the text. I have used 500 for this. This could change based on your own tests. Try to increase this value if the auto sizing is not done properly.

Conclusion

As you can see, it is really quite simple to get the DataGrid to auto size.  I am really surprised that Microsoft hasn’t built this into the DataGrid as a default behavior. So till that time, auto sizing needs this extra bit of code.

Please rate the quality of this article
Poor
Outstanding
Tell me why you rated this content this way. (optional)
 
Rating Spread

  

Copyright 2002-2005 Sai Panyam   Terms Of Use  Privacy Statement