DataGridView has a lot of smarts built into it so that it can easily deal with presenting a large grid in a small Form, but many times the developer would prefer to automatically expand the Form in order to show all (or most) of the grid rather than make the user do so manually. Such functionality is not built into the framework, and a quick online search will turn up many developers seeking a solution.
Something the user (and therefore the developer) will likely wish to avoid is having a Form expand to enormous proportions, so some ability to constrain the size of the Form is desired. The solution I present below has two methods to control the maximum size of the Form.
Similarly, when presenting a very small grid, having the Form contract to such a small size that other controls on the Form are not visible would not be desirable.
I wrote this method to support a WinForms application that needs to present a grid and a few buttons in a dialog. It appears to work well in this capacity though I'm unsure how well-suited it would be for use in a main Form. I have also not tried it with more than one
DataGridView on one Form.
Using the Code
Download the attached source code and include it in your project.
Before calling this method, please be sure you have all the properties of the
DataGridView set the way you like. For instance, if you are going to hide columns or enable row and column auto-resizing, you should do so before calling this method.
Similarly, be sure that the
MaximumSize properties of the Form are set the way you want before calling this method.
The method also accepts a
Rectangle to use as a constraint which limits the Form to an area of the user's screen(s). A constraint is similar to setting the
MaximumSize of the Form, but it also allows the Form to be moved. For the application I'm working on, I use
System.Windows.Forms.Screen.FromControl ( Grid ).Bounds as a constraint to ensure that the Form stays on one physical monitior; the user may then manually resize the Form beyond that size. A value of
System.Drawing.Rectangle.Empty acts as "no constraint".
If you do not constrain the Form with either
MaximumSize or a
Constraint rectangle, then the user may wind up with a very large Form that extends well beyond his physical monitor(s). Please be sure that that is the desired behaviour before you release such an application to your users.
There are some other options that can be specified and I'll discuss them as we go along. The options are bitmapped flags, of course.
The process of calculating the size required to show the whole grid is pretty simple.
Calculate the desired width
int width = lagniappe ;
width += form.Width - Grid.Width ;
width += Grid.RowHeadersWidth ;
for ( int i = 0 ; i < Grid.ColumnCount ; i++ )
if ( Grid.Columns [ i ].Visible )
width += Grid.Columns [ i ].Width ;
Calculate the desired height
int height = lagniappe ;
height += form.Height - Grid.Height ;
height += Grid.ColumnHeadersHeight ;
for ( int i = 0 ; i < Grid.RowCount ; i++ )
if ( Grid.Rows [ i ].Visible )
height += Grid.Rows [ i ].Height ;
lagniappe is a constant that I add in order to avoid scroll bars in certain situations; you may need to adjust it, but the value 2 works on my system.
This gives us the total width and height required to show the whole grid, but it may be too small or too big, so...
Honor the MinimumSize of the Form when requested
HonorMinimumSize is an option that can be specified.
if ( ( Options & ResizeFormOption.HonorMinimumSize ) == ResizeFormOption.HonorMinimumSize )
if ( width < form.MinimumSize.Width )
width = form.MinimumSize.Width ;
if ( height < form.MinimumSize.Height )
height = form.MinimumSize.Height ;
Honor the MaximumSize of the Form when requested
HonorMaximumSize is an option that can be specified.
if ( ( Options & ResizeFormOption.HonorMaximumSize ) == ResizeFormOption.HonorMaximumSize )
if ( ( form.MaximumSize.Width > 0 ) && ( width > form.MaximumSize.Width ) )
width = form.MaximumSize.Width ;
if ( ( form.MaximumSize.Height > 0 ) && ( height > form.MaximumSize.Height ) )
height = form.MaximumSize.Height ;
This size is saved as the
Apply Constraint when requested
Rectangle other than
Rectangle.Empty to apply a constraint. No validation of the constraint will be performed; please be sure to provide a meaningful rectangle.
if ( Constraint != System.Drawing.Rectangle.Empty )
if ( width > Constraint.Width )
form.Left = Constraint.X ;
width = Constraint.Left + Constraint.Width - form.Left ;
else if ( width > Constraint.Left + Constraint.Width - form.Left )
form.Left -= width - ( Constraint.Left + Constraint.Width - form.Left ) ;
if ( height > Constraint.Height )
form.Top = Constraint.Y ;
height = Constraint.Y + Constraint.Height - form.Top ;
else if ( height > Constraint.Top + Constraint.Height - form.Top )
form.Top -= height - ( Constraint.Y + Constraint.Height - form.Top ) ;
This size is saved as the
minsize and we try to resize the Form to this size.
Throw is an option that can be specified. Resizing the Form may throw an
ArgumentOutOfRangeException, and the caller may choose whether or not to swallow such an exception once it has been caught. If this option is not specified, and this type of exception is encountered, then the return value will be set to
catch ( System.ArgumentOutOfRangeException err )
if ( ( Options & ResizeFormOption.Throw ) == ResizeFormOption.Throw )
err.Data [ "Top" ] = form.Top ;
err.Data [ "Left" ] = form.Left ;
err.Data [ "Width" ] = width ;
err.Data [ "Height" ] = height ;
result = false ;
Freeze the Form when requested
Freeze is an option that can be specified. This will set the
MinimumSize properties of the Form, and, if they are equal, it will set the
FormBorderStyle to fixed. This limits the ability of the user to manually resize the Form.
A Form that expands well beyond the user's physical monitor(s) and then becomes non-resizable would be considered user-hostile, so please don't
Freeze a Form unless you have also constrained it to a reasonable size. You have been warned.
if ( ( Options & ResizeFormOption.Freeze ) == ResizeFormOption.Freeze )
form.MaximumSize = maxsize ;
form.MinimumSize = minsize ;
if ( minsize == maxsize )
switch ( form.FormBorderStyle )
case System.Windows.Forms.FormBorderStyle.Sizable :
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle ;
case System.Windows.Forms.FormBorderStyle.SizableToolWindow :
form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow ;
This method does what I need it to on my system, but I have also seen it behave a little oddly (nothing catastrophic) on a colleague's system and I haven't yet spent any time tracking down the cause -- I think it's due mainly to Windows themes, but I could be wrong.
I have performed only minimal testing and not thrown unusual values at it. Any feedback on how it behaves on your system(s) would be appreciated.
- 2016-01-03 First submitted