Autosize a DataGridView to Fit | CodeGuru

Autosize a DataGridView to Fit

This article describes how you can resize a dbgrid to always fit the form after a resize so that you never have a horizontal scrollbar. Description What the code does is first recalculate all columns’ width (if you have visible columns). But, at the end, you could have rounding errors and still have a scrollar […]

Written By
CodeGuru Staff
CodeGuru Staff
Jun 13, 2005
3 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

This article describes how you can resize a dbgrid to always fit the form after a resize so that you never have a horizontal scrollbar.

Description

What the code does is first recalculate all columns’ width (if you have visible columns). But, at the end, you could have rounding errors and still have a scrollar if the last column is 1 or more pixels too wide. So, at the end you calculate the exact width needed for the last column.

Let me describe some importand code fragments.

int fixedWidth = SystemInformation.VerticalScrollBarWidth +
   dataGrid.RowHeadersWidth + 2;
int mul = 100 * (dataGrid.Width - fixedWidth) /
   (prevWidth - fixedWidth);

First, check the fixed width of the datagrid. This is the width of the scrollbar and the width of the row headers. You include the row headers because resizing these is very ugly. Now, what about this multiplying by 100? You are going to multiply/divide the width of the columms with a number containing a decimal point (for example, if you make the form 50 percent, you will multiply by 0.5). But, working with float numbers is very slow and not needed with a little imagination). So, you take an integer and multiply by 100 to get 2 decimal fractions.

The correction of adding 2 pixels to the fixedWidth is important. This is dependent on the BorderStyle of the grid. You need the 2 pixel if it is set to FixedStyle. You don’t need it when it is set to None, and you have to increase it if set to Fixed3D, of course.

Then, you step trough all visible columns to calculate the new width. Of course, you take into account that there is a MinimumWidth property.

columnWidth = (dataGrid.Columns[i].Width * mul + 50)
   / 100;
dataGrid.Columns[i].Width =
   Math.Max(columnWidth,
   dataGrid.Columns[i].MinimumWidth);

What about thie + 50? Well, remember that we emulate a floating point with integer. So, by adding 50 before dividing by 100, you round it. If you do not, we truncate, and with every resize each column will be a little smaller and smaller.

The last thing to do is check the exact width of the last column. This is nececary because you could have little rounding errors, or be limited by the MinimumWidth of some columns. Then, you end up with either a scrollbar or a blank space after the last column, both of which is very ugly.

Complete Code

public void ResizeGrid(DataGridView dataGrid, ref int prevWidth)
{
   if (prevWidth == 0)
      prevWidth = dataGrid.Width;
   if (prevWidth == dataGrid.Width)
      return;

   int fixedWidth = SystemInformation.VerticalScrollBarWidth +
      dataGrid.RowHeadersWidth + 2;
   int mul = 100 * (dataGrid.Width - fixedWidth) /
      (prevWidth - fixedWidth);
   int columnWidth;
   int total = 0;
   DataGridViewColumn lastVisibleCol = null;

   for (int i = 0; i < dataGrid.ColumnCount; i++)
      if (dataGrid.Columns[i].Visible) {
         columnWidth = (dataGrid.Columns[i].Width * mul + 50) / 100;
         dataGrid.Columns[i].Width =
            Math.Max(columnWidth, dataGrid.Columns[i].MinimumWidth);
         total += dataGrid.Columns[i].Width;
         lastVisibleCol = dataGrid.Columns[i];
      }
   if (lastVisibleCol == null)
      return;
   columnWidth = dataGrid.Width - total +
      lastVisibleCol.Width - fixedWidth;
   lastVisibleCol.Width =
      Math.Max(columnWidth, lastVisibleCol.MinimumWidth);
   prevWidth = dataGrid.Width;
}
Advertisement

Test Application

This is how to use it. Note that you have two variables in your form, to remember the WindowState and the last width.

You do not recalculate in the Resize event because there will be so many recalculations (especially when the user resizes very slowly) that you will get out of proportion due to rounding errors. So, you use ResizeEnd to calculate one time after resizing. But, you also need to recalculate when the user maximizes or restores the form. That you do in the Resize event.

This is the complete code:

namespace ResizeGridDemo
{
   public partial class main: Form
   {
      int prevWidth;
      FormWindowState prevWindowState;

      public main()
      {
         InitializeComponent();
         prevWidth = Width;
         prevWindowState = WindowState;
      }

      private void main_ResizeEnd(object sender, EventArgs e)
      {
         ResizeGrid(dataGrid, ref prevWidth);
      }

      private void main_Resize(object sender, EventArgs e)
      {
         if (WindowState != prevWindowState && WindowState !=
             FormWindowState.Minimized) {
            prevWindowState = WindowState;
            ResizeGrid(dataGrid, ref prevWidth);
         }
      }
   }
}

Summary

Rather that put all this code in a form, it could be in a subclass of DataGridView, or even in a new component derived from it.

Note: I use VS beta 2. Things can be different in the .NET 1.1 version.

If you use this code in a project, you only need it one time; for example, in a static class. Each form must have the prevSize variable, and if the form can be maximized, it also needs the prevWindowState variable.

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.