Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#, Windows Forms, Best/min fit window to contents

Tags:

c#

.net

winforms

I have a form with some controls. (Actually, this is a sort of ongoing problem.) Some of the forms I have had are resizable, some are not. Regardless, when the form is displayed, it would be nice to have it appear in the "minimum" size needed. Other Windowing toolkits, such as wxWidgets (wxWindow::GetMinSize) and Qt (QWidget::minimumSize) have this functionality.

This functionality, if you are not familiar with it, allows a window to resize itself to a minimum size, which is often all the window needs, and looks quite nice. If I have two static texts, and two edit boxes laid out thusly:

Username:
[ Edit/text box for user's password]
Password:
[ Edit/text box for user's password]
              [  Cancel  ][   OK   ]

I can then tell this form to size itself to it's "minimum size", and it would appear much like above. (Minimum width in a text box is partly subjective - I would have to set that myself in one/both of the text boxes, but the form would query the child controls and learn of that minimum width) This is usually combined with layouts of some sort. (Which .Net has.)

This has the added benefit that the form is the correct size regardless of font settings, locale, dpi, gui skin, etc. (If done right, at least.)

Does this exist in .Net, and if so, where? If you need any more description, ask, and I'll be glad to provide.

Edit: What I'm looking for is the above example, resizable only in the X direction (I'm willing to accept both) but can't be resized smaller than a certain W/H. The controls should anchor - ie, the text boxes get bigger, the buttons stay right aligned.

Edit: I can do images! Supposedly they're worth a thousand words: alt text http://www.freeimagehosting.net/uploads/79e9ee10e5.png

Edit: I guess I'm going to start marking answers. Henk's answer has gotten me pretty far with a non-resizable dialog that fits to it's contents. Most of the posts below are valuable, but miss the point (unless I'm really off base here?): I understand how to use Anchor/TableLayout, and to get controls to flow there - it was mostly getting one or both dimensions of the dialog to fit to the contents of the dialog. You essentially have three cases:

  1. The dialog is not resizable - See Henk's answer. Combined with TableLayout and Anchors, you'll get a decent dialog.

  2. The dialog is only resizable in one dimension - Go with 1 or 3 - You can constrain a dimension by using the Resize event, but the dialog flickers horribly. (This seems to be a defect in Win32 as far as I can tell - there is some stuff out there about overriding the background erase, which works for controls, but not windows, as you'll get artifacts in the form's background (because you're not erasing them). The real answer is that this should probably be handled by Win32 itself - I should not have to reinvent the double-buffer wheel just to get a decent look dialog...))

  3. The dialog is fully resizable. Anchors and TableLayout are your friend. Unfortunately, the MinimumSize attribute seems to be bogus (at least, I don't know what it is for...) - for example, if you query the MinimumSize of a textbox, by default the height is 4 pixels. Further, the MinimumSize property doesn't seem to propogate - a control does not query it's children. (I can resize the form smaller than the textbox within the form, and the textbox is then off the form.) If you wonder what I'm babbling about, see wxWidgets and how layouts and minimum size work for it.

I've also since discovered that .Net does not seem to respect the system font, and always uses the same font for Forms, so font changes won't affect my dialog (sadly) which alieviates most of my worries (happily?). Again, refer to how wxWidgets does it - if the system font is 22pt, all wxFrames (forms) respect and resize appropriately. .Net should get onboard this train... (And I know someone who uses 22+pt font day-to-day for their standard GUI font.)

like image 853
Thanatos Avatar asked May 14 '09 15:05

Thanatos


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C language basics?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


2 Answers

There is something that comes close, try the following: design your Form a bit large and avoid Right and Bottom docked controls. Then some code like this:

private void button1_Click(object sender, EventArgs e)
{
    this.AutoSize = true;
    this.Size = new Size(10, 10);
}

The AutoSize will find the extend of the Controls.

like image 112
Henk Holterman Avatar answered Oct 20 '22 04:10

Henk Holterman


I handle these sort of things using TableLayoutPanel. TableLayoutPanel lets you layout your controls in columns and rows. Columns and rows have three SizeTypes: AutoSize, Percent, and Absolute. AutoSize sizes the column or row according to the minimum necessary value, Percent sizes the column or row according a percent of unused area, and Absolute sizes the column or row according to an absolute number of pixels.

The VisualStudio designer is helpful. If you would rather write all code by hand, it is still a good idea to play with TableLayoutPanel in the designer and examine the resulting designer code to learn how to operate TableLayoutPanel.

In order to get the minimum necessary size, you should:

  • Dock.Fill the TableLayoutPanel in your form.
  • Dock.Fill controls in cells.
  • Handle spacing between controls using Control.Margin.
  • Make the SizeType of all the columns and rows AutoSize.

Also, you can use ColumnSpan and RowSpan to make a control take up multiple cells.

Once you set things up the way you want them to look, you can use TableLayoutPanel.GetPreferredSize() to determine the minimum required area of the TableLayoutPanel and assign that value to Form.ClientSize.

If the user will be able to resize your form, after you determine the minimum required size you should set the SizeType of the column and row you want to grow with the form to SizeType.Percent and use a value of 100, like this:

// "columnIndex" is the zero based index of the column
this.tableLayoutPanel.ColumnStyles[columnIndex] = new ColumnStyle(SizeType.Percent, 100);

// "rowIndex" is the zero based index of the row
this.tableLayoutPanel.RowStyles[rowIndex] = new RowStyle(SizeType.Percent, 100);
like image 43
Zach Johnson Avatar answered Oct 20 '22 02:10

Zach Johnson