Introduction
Over the years, I have seen many developers designing Windows Forms by just dragging and dropping controls, and then repositioning them to match their requirements. When they need to change anything in the design, or when they add a new control, it becomes a little bit messy.
Here is a small demonstration of the technique I use to design Windows Forms, by using a control called TableLayoutPanel
. I know that there are so many other techniques, others might use docking properties and anchors for example, but I also intended for this tip to be a discussion forum, where I can also learn about other techniques.
Background
TableLayoutPanel
is a control that "Represents a panel that dynamically lays out its contents in a grid composed of rows and columns" (From MSDN: TableLayoutPanel Class).
Basic Requirement
In this sample, we are required to build a simple manual entry form like the below, with some conditions:
Whatever the size of the form (down to a certain extent), even when the form is maximized, the following should always remain true:
- The size of the text boxes must remain equal for all text boxes, and they must fill the largest space available
- The labels must all be left aligned
- The Grid View must fill all of the remaining space
- A small refresh button must exist below the Grid, it must always be aligned to the right of the form.
Implementation
First let us create a new Windows Forms Applications Project. Expand the main form, and add a new TableLayoutPanel
control by dragging it from the Toolbox menu under the "Containers" section.
Expand the new control till it fills the form, and Modify the Anchor
property to attach to the 4 sides: "Top, Right, Bottom, Left". name the control "tblPnlMain
".
Add a new Row to the table panel by clicking the small arrow at the right side of the panel, and then choosing "Add Row".
Now remove the last column by clicking the button "Remove Last Column". After that, in the first row, add another TableLayoutPanel
and name it "tblPnlDataEntry
". In this panel, we will be placing our labels, text boxes, save and cancel buttons.
Add two additional columns and two additional rows to this new panel.
Set the Anchor
of this panel to take all of the four sides, then expand the panel to fill all of its parent container. Please note that in one cell of the table panel, we can only put one control. That's why we are putting a table panel to be able to add controls as much as we want.
Add 6 labels to the first and third column of the data entry manual form. Set the Anchor
of all of them to be just "Left". Set their text properties as: "First Name, Last Name
", "Mobile Phone
", "Home Phone
", "Billing Addresses
" and "Country
". Don't worry about the design now, we will fix that shortly.
Now, in the 2nd and 4th column of the data entry panel, add 6 text boxes. Set the Anchor to all of them to be "Left and Right". This will allow the text boxes to fill the whole width of their parent containers. You will end up with an ugly form like the below:
Now, click on the small arrow on the right side of the Data Entry table panel, and choose "Edit Rows and Columns". For Column 1 and Column 3, set the size type to "Autosize
", this will force the columns to take the width of the largest child control. For Column 2 and Column 4, set the size type to "Percent
", and set the value to 50% for each column. This will tell the columns to take 50 % of the remaining space each.
This will fix our form:
Now, in the 4th row, last column, add another table panel, name it "tblPnlButtons
". For this panel, remove the last row, so that it has only two columns. In the first column, add a button and caption it as "Save". In the second column, add another button and caption it as "Cancel". Set the Anchor
property for this panel to Right only. Also set the Anchor
for both Buttons to "Right". The form will now look like this:
Now back to the Data Entry Table Panel, Click Edit Rows and Columns, choose the "Rows" item in the drop down list, set the first 3 rows to "AutoSize
", and set the 4th row to "Percent
", giving it 100%, this means that the last row will take all of the remaining space.
Now the form should look like this (if the buttons are still small and not appearing in full, try to expand your form a little bit).
Still something is not right, the Save and Cancel Button are too far from each other. Open the "Table Layout Panel Tasks" for the Buttons table panel, and set the size type of the first column to "Percent
", and the value to 100%, for the second column, set the size type to "AutoSize
".
Now the form will look like this:
Add a Grid View to the second row of the main table panel, and add a button to the last row. Set the Anchor
of the grid view to all four sides (Top, Right, Bottom, Left), and set the Anchor
of the button to Right. Caption the Button as "Refresh".
Open the Table Layout Panel Tasks for the Main table panel, and set the size type of the first row and last row to "AutoSize
", and the size type of the second row to"Percent
", and the value to 100%. Setting the Size percent of the second row to 100% will ensure that the Grid View will take all of the remaining space.
The completed form will look like this:
Now run the form, resize it, and then maximize it. You will see that the controls are always in order. Set the minimum size of the form to a value of your choice, to ensure that the controls have the minimum space they require to remain in order.
Now for example if you set the Form's "Right to left" property to true
, you will notice that all the controls will still be in place, in order, and with the same proportions. This is one example of the benefits of a TableLayoutPanel
, it takes a little bit of effort at the beginning, but it will save you a lot of work later on.
Bonus Tip
This is an update to the original post. Suppose your manual entry form needs more data, you need to add a checkbox which will indicate if the person is married or not. If the person is married, 4 entry fields should appear in the control: Spouse name, spouse last name, spouse age and number of children. If the person is not married, these entry fields should disappear, and the controls should resize to fill the empty space. The final design should look like this:
If the user unchecks the checkbox, the form will change to this, notice how the "Save" and "Cancel" buttons will move up to below the "Is Married" checkbox, and the Grid View will expand to fill up the empty space.
To begin, go the data entry table panel and add three more rows:
Expand the table panel to have more space to add the new controls.
Move the buttons table panel to the last row, the form will now look like below:
Now add 5 labels, set their anchors to left only, and caption them as shown below:
Add a checkbox control to the cell adjacent to the "Is Married" label. Set its Anchor
to "Left" and set its Text
property to empty string. Now add four text boxes next to the four new labels. Set their Anchor property to "Right" and "Left".
Now this is important: Set the buttons table panel Anchor
to "Top" and "Right", and for the Data Entry Panel, there is a property named "AutoSize
". This will specify if the panel will automatically resize to fits its content, set this property to "True".
Now still in the Data Entry Panel, Open the "Edit Rows and Columns" box from the "TableLayoutPanel Tasks", and set the Size type for the first 6 rows to "Auto Size", and set the Size type for the last row to "Percent", set its value to 100%.
The form will now look like this:
Expand it a little bit, so that the "Save" and "Cancel" buttons are completely visible:
Now double click on the checkbox next to the "Is Married" label and add the below code, this will hide or show all the new labels and text boxes based on whether this checkbox is checked or not. Set the Checked property of the checkbox to true so that it is checked by default when the form runs:
label8.Visible=label9.Visible=label10.Visible=label11.Visible=checkBox1.Checked;
textBox7.Visible = textBox8.Visible = textBox9.Visible =
textBox10.Visible = checkBox1.Checked;
Now run the form, When expanded, it will look like this:
When you uncheck the "Is Married" checkbox, the form will automatically reposition and resize its controls accordingly:
You can download the updated sample code from the top of the tip, thanks for following up :).