Responsive layouts - RobinPerris/DarkUI GitHub Wiki

WikiResponsive layouts

Creating high quality layouts in WinForms can be a bit of a chore. Personally I make use of the Dock property to make sure my controls properly fill and conform to the container they're presented in.

The controls in DarkUI were designed to be used in much the same way.

Form and dialog spacing

To properly dock controls within a form we first need to define some whitespace which properly separates the content from the parent container.

First, we'll start off with a blank form or dialog.

DarkDialog

Then we add in a Panel control and set the Dock property to Fill. If we're using a blank form, we'll give this a Padding of 10, 10, 10, 10. If it's a dialog, the footer already includes 10 pixels of padding, so we'll set the padding to 10, 10, 10, 0.

With this panel in place, we can now add in some controls. Personally I like using the DarkSectionPanel control to properly define an area within the form.

Section panel

If we then add in a DarkListView with a Dock value of Fill and a DarkToolStrip with a Dock value of Bottom we'll be able to get a simple, responsive control layout which will automatically size itself based on the size of the container form.

Responsive layout

Section spacing

Unfortunately the WinForms Margin property doesn't work quite like you'd expect if you come in from a web-development background. There are some controls you can use to make this easier, such as the TableLayoutPanel, however for spacing out individual panels I prefer to keep controls separate.

Let's modify our previous example and bring up a situation which requires more in-depth layout work.

Take the parent Panel you created and set the Dock property to Left, then re-size the parent form to open up space for a second section.

Larger form

We want to modify the panel on the left to contain three DarkSectionPanel controls instead of just one. To do this, we'll first add some additional Panel controls to dictate the vertical margins.

First, move the existing DarkSectionPanel out of the left section panel so we can properly work in that control.

Second, add three new Panel controls. Set the Dock property of the top two panels to be Top. Set the third panel's Dock property to be Fill. This will ensure that the sum of all the panels will match the vertical size of the parent form.

Panels

Now take our previous DarkSectionPanel and place it within the bottom-most panel and add in additional DarkSectionPanel controls to the top two panels. Make sure all of these have their Dock property set to Fill.

Also set the top two parent panels to have 10 pixels of bottom padding. This will make sure there is adequate spacing between the visible section panels.

Section panels

We now have a pretty nice layout for the left column of our layout.

To finish up the rest, add a Panel control in the main form with the same padding value of your left column panel. Add a final DarkSectionPanel and set the Dock property to be Fill.

To make sure there's not too much padding between the left and right sections change their padding properties so the Right and Left values are 5 instead of 10. This will ensure the total padding between them matches the other areas.

Complete layout

Control spacing

So now we have some sections which properly conform to the size of the form. We've also seen how to create basic control layouts using the Dock property.

However, what if we want to create a vertical control flow which includes margins between each row? We use the TableLayoutPanel control.

As the DarkSectionPanel control doesn't support padding, you'll need to create a new Panel control which has 10 pixels of padding instead. Drag that in to the main DarkSectionPanel control, set the Dock property to Fill and then add in a TableLayoutPanel.

Table layout panel

Whilst the control has focus, clicking the arrow in the top right of the TableLayoutPanel will open up a menu. Selecting Edit rows and columns... will open up a dialog which allows you to customise the layout.

Column and row styles

As we'll only be using a single column for this example, you can delete the second one. Setting the first column to AutoSize will cause it to automatically fill the panel.

Switching to the row view, we'll now create as many rows as we think we'll need. We can always add more later. Setting each of these to have a size type of AutoSize will cause them to automatically wrap around their contents.

Accept your changes and your TableLayoutPanel is now ready to accept your controls. Drag in some labels and textboxes and you'll be able to create a simple vertical layout flow.

As you do so, make sure their Row and Column properties are set properly, as the designer is a bit temperamental about these. Also, make sure to remove the Margin from each of them to stop the default values from screwing up your flow.

Vertical flow

It looks pretty terrible, doesn't it. The TableLayoutPanel actually respects the Margin properties of its child controls, so we'll now be able to use that to properly space out our controls.

As a rule of thumb I use a 10 pixel margin at the top and bottom of a section, then 5 pixel margins between controls within a section.

Margins

So there we have it. A dynamic control flow which maintains consistent spacing between controls and properly sizes based on the parent container.

You can get a lot more clever with the layouts. Here's an example of one of the control layouts from my own application.

Structure editor

Remember - spacing is everything.