Click here to Skip to main content
14,242,360 members

Resize Form To Fit DataGridView

Rate this:
5.00 (1 vote)
Please Sign up or sign in to vote.
5.00 (1 vote)
4 Jan 2016CPOL
Attempts to resize a Form to show the entire table of a DataGridView

Introduction

The WinForms 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 MinimumSize and 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.

Example:

PIEBALD.Lib.LibWin.ResizeFormToFitDataGridView
(
  myGrid
,
  System.Drawing.Rectangle.Empty
,
  PIEBALD.Lib.LibWin.ResizeFormOption.HonorMinimumSize
  |
  PIEBALD.Lib.LibWin.ResizeFormOption.HonorMaximumSize
) ;

ResizeFormToFitDataGridView

The process of calculating the size required to show the whole grid is pretty simple.

Calculate the desired width

int width  = lagniappe ;

/* Add the current width of the form outside the Grid */
width += form.Width - Grid.Width ;

/* Add the width of the row headers */
width += Grid.RowHeadersWidth ;

/* Add each visible column's width */
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 ;

/* Add the current height of the form outside the Grid */
height += form.Height - Grid.Height ;

/* Add the height of the column headers */
height += Grid.ColumnHeadersHeight ;

/* Add each visible row's height */
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 ;
  }
}

maxsize

This size is saved as the maxsize.

Apply Constraint when requested

Provide a 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 the preferred width won't fit the Constraint */
  if ( width > Constraint.Width )
  {
    /* slide it all the way to the left */
    form.Left = Constraint.X ;

    /* and clip the size to extend only to the right edge */
    width = Constraint.Left + Constraint.Width - form.Left ;
  }
  /* If the preferred width would extend beyond the right edge of the Constraint, */
  else if ( width > Constraint.Left + Constraint.Width - form.Left )
  {
    /* slide the Form toward the left */
    form.Left -= width - ( Constraint.Left + Constraint.Width - form.Left ) ;
  }

  /* If the preferred height won't fit the Constraint */
  if ( height > Constraint.Height )
  {
    /* slide it all the way to the top */
    form.Top = Constraint.Y ;

    /* and clip the size to extend only to the bottom edge */
    height = Constraint.Y + Constraint.Height - form.Top ;
  }
  /* If the preferred height would extend beyond the bottom edge of the Constraint, */
  else if ( height > Constraint.Top + Constraint.Height - form.Top )
  {
    /* slide the Form toward the top */
    form.Top -= height - ( Constraint.Y + Constraint.Height - form.Top ) ;
  }
}

minsize

This size is saved as the minsize and we try to resize the Form to this size.

Handling ArgumentOutOfRangeExceptions

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 false.

/* Resizing across screen boundaries may cause ArgumentOutOfRangeExceptions */
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    ;

    throw ;
  }

  result = false ;
}

Freeze the Form when requested

Freeze is an option that can be specified. This will set the MaximumSize and 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 ;

        break ;
      }

      case System.Windows.Forms.FormBorderStyle.SizableToolWindow :
      {
        form.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow ;

        break ;
      }
    }
  }
}

Conclusion

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.

History

  • 2016-01-03 First submitted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

PIEBALDconsult
Software Developer (Senior)
United States United States
BSCS 1992 Wentworth Institute of Technology

Originally from the Boston (MA) area. Lived in SoCal for a while. Now in the Phoenix (AZ) area.

OpenVMS enthusiast, ISO 8601 evangelist, photographer, opinionated SOB, acknowledged pedant and contrarian

---------------

"Using fewer technologies is better than using more." -- Rico Mariani

"Good code is its own best documentation. As you’re about to add a comment, ask yourself, ‘How can I improve the code so that this comment isn’t needed?’" -- Steve McConnell

"Every time you write a comment, you should grimace and feel the failure of your ability of expression." -- Unknown

"If you need help knowing what to think, let me know and I'll tell you." -- Jeffrey Snover [MSFT]

"Typing is no substitute for thinking." -- R.W. Hamming

"I find it appalling that you can become a programmer with less training than it takes to become a plumber." -- Bjarne Stroustrup

ZagNut’s Law: Arrogance is inversely proportional to ability.

"Well blow me sideways with a plastic marionette. I've just learned something new - and if I could award you a 100 for that post I would. Way to go you keyboard lovegod you." -- Pete O'Hanlon

"linq'ish" sounds like "inept" in German -- Andreas Gieriet

"Things would be different if I ran the zoo." -- Dr. Seuss

"Wrong is evil, and it must be defeated." –- Jeff Ello

"A good designer must rely on experience, on precise, logical thinking, and on pedantic exactness." -- Nigel Shaw

“It’s always easier to do it the hard way.” -- Blackhart

“If Unix wasn’t so bad that you can’t give it away, Bill Gates would never have succeeded in selling Windows.” -- Blackhart

"Use vertical and horizontal whitespace generously. Generally, all binary operators except '.' and '->' should be separated from their operands by blanks."

"Omit needless local variables." -- Strunk... had he taught programming

Comments and Discussions

 
QuestionExactly what I needed Pin
obermd3-Jun-19 4:04
memberobermd3-Jun-19 4:04 
QuestionWhich event? Pin
dherrmann23-Jan-16 23:06
memberdherrmann23-Jan-16 23:06 
AnswerRe: Which event? Pin
PIEBALDconsult24-Jan-16 4:17
protectorPIEBALDconsult24-Jan-16 4:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Tip/Trick
Posted 4 Jan 2016

Stats

14.2K views
273 downloads
3 bookmarked