Layout Techniques for Windows Forms Developers

In a typical Windows Forms application control placement is set using
the Location property, setting the X and Y sub property values. The
Windows Forms designer provides a complete set of tools for aligning and
sizing controls.

The WPF and Silverlight platforms are different in both available tooling and layout options.

This
article will demonstrate some form layout techniques to help Windows
Forms developer’s make the transition to WPF or Silverlight.

We’ll
first lay the form out using the same familiar techniques you’re used
to in Windows Forms; then we’ll create the form using a typical WPF
& Silverlight workflow.

Requirements

Please read the WPF & Silverlight Layout Controls topic.

Application 

This
simple Windows Forms dialog took about 90 seconds to layout. The
Windows Forms designer provided excellent layout adorners to assist in
aligning the controls. The Properties Window was utilized to set control
anchoring and enter the Label and Button text.

This
simple WPF dialog took about 90 seconds to layout. The designer
provided excellent layout adorners to assist in aligning and set
anchoring on the controls. The Properties Window was utilized to enter
the Label and Button text.

Let’s Build This Dialog in WPF

  • Add a new WPF Window to the project and name it Customer.xaml
  • Click the design surface outside the boundary of the Window to select the Window object
  • Using
    the lower left resize adorner, resize the Window to 350 x 300. Notice
    the resize adorner labels indicate the size as you resize the Window.

  • Drag and drop a Label control from the ToolBox to the design surface inside the Window
  • Notice
    the blue box adorner that gets displayed along with the inner area
    changing color to white when you drag the Label from the ToolBox. This
    is the Drop Target feature of the WPF and Silverlight Designer,
    providing you feedback where the object you are dragging can be dropped.

  • After
    dropping the Label, move it to the upper left corner. Notice edge snap
    line adorners providing assistance as you get near the top and left
    edges.
  • The number in the top left corner indicates the
    distance to each edge. The top right and bottom left adorners indicate
    how far the control is from those edges.

  • With
    the new Label selected on the design surface, use the Properties Window
    to set the Label text to, First Name. In WPF and Silverlight this is
    accomplished by changing the Content property.

  • Add a TextBox to the form
  • To easily position the TextBox to line up with the Label, the text baseline adorner displays helping you line up the controls

  • After moving the TextBox, the selected adorners will now display as pictured below
  • The small square adorners at each corner are used to resize the TextBox
  • The
    below TextBox is anchored left and top. This is indicated by the left
    and top triangles the red arrows point to. Since the left edge of the
    TextBox is great than a few pixels from the edge, the anchoring adorner
    line is displayed.
  • To now anchor this TextBox to the right also, we just need to click the right circle the right red arrow points to

  • After clicking the right circle, the right edge anchoring adorner is displayed
  • Windows Forms terminology
    • TextBox is anchored left, top and right
  • WPF and Silverlight terminology
    • TextBox has HorizontalAlignment set to Stretch and VerticalAlignment set to Top

  • Now
    resize the TextBox. When resizing, notice the right edge snap line that
    appears down the length of the right edge. This indicates that the
    control is 12px from the edge.

  • Marquee select the Label and TextBox control

  • Release the mouse and right click the selected TextBox, select Copy

  • Click the inner area of the Window, right click and select Paste
  • The newly pasted controls will appear on top of the existing controls
  • Notice the newly pasted controls are selected

  • Click and drag the TextBox down; the Label will move with the TextBox
  • As
    you are dragging down, notice that the designer snaps at two
    increments, 6px and 14px. For this application, we are using 14px.

  • Repeat the select, copy, paste and align action two more times
  • Change the Label Content property as indicated below

  • Drag and drop a RadioButton below the bottom TextBox
  • Move it into the position shown below
  • Notice the left control edge snap line and the control distance adorner value of 14

  • Drag and drop a new Label control below the Phone Label. Move it below the Phone Label as pictured below.
  • Notice the left edge snap line provides an easy guide for the left edge
  • As you drag the new Label control down use the text baseline snap line of the RadioButton to align the control

  • Change the new Label to read Gender and set the Content property on the RadioButton to Male
  • Drag and drop a new RadioButton control to the design surface and move it into place as pictured below

  • Change the text of the new RadioButton to Female
  • Add a new Button to the design surface and move it into position as shown below

  • After releasing the mouse the selection adorners will appear as pictured below
  • Now anchor this button right and bottom:
    • Click the left adorner, this will toggle anchor left to anchor right
    • Click the top adorner, this will toggle anchor top to anchor bottom
    • In WPF and Silverlight terminology the Button now has HorizontalAlignment set to Right, VerticalAlignment set to Bottom

  • Copy and paste the Button, then move into the position below.

  • Change the Button’s text as pictured below by using the Properties Window to change the Content property of each Button.
  • You
    can test the layout by resizing the Window control. Notice that the
    Buttons stay anchored to the bottom right and the TextBoxes resize with
    the Window.

Easily Change to a Resizable Two Column Form

Now
that we see creating a form in WPF or Silverlight is very similar to
the Windows Forms experience, let’s look at how WPF or Silverlight
easily enables making the above form a two column form. The two column
form we will create will resize when the Window is resized.

Before proceeding, think about the steps you would follow using the Windows Forms platform to accomplish the task.

Under the Covers

The
Windows Forms Designer persists changes to a hidden code-behind file.
The WPF and Silverlight Designer persists changes to XAML. To view the
created XAML you can click on the XAML View Button. The XAML View and
Design View buttons are located at the bottom of the Visual Studio tab
you have been working with.

If your XAML is not currently visible, click the XAML View button.

Your XAML should look similar to the below image.

What I want to point out is the second element in the XAML, the Grid.

The
entire time we have been adding controls to the form, we have actually
been adding them as a child of the Grid control. The Grid is one of the
available layout panels.

When the Grid has no rows or columns
defined, it’s effectively a single cell grid, positioning its child
controls using Margin, HorizontalAlignment and VerticalAlignment
properties. In similar fashion, Windows Forms uses Location and Anchor
properties.

I’ve show the Grid control here because in the next step we will being working with it.

In WPF or Silverlight the simple steps to create a two column form are:

  • Click on the Design View button to bring the designer back into view
  • Right click on the Grid (the area inside the Window, not occupied by a child control), select Grid Column, Insert After

  • The form should now look like the below image
    • The
      Grid Column, Insert After function adds a new column after the current
      column and sets its width to 126px. Notice the 126 in the right column
      rail adorner.
    • The left column size is displayed also; 1*. Star sizing is proportional sizing and is fully explained in this article WPF & Silverlight Layout Controls.

  • With
    the Grid selected, locate the ColumnDefinitions property in the
    Properties Window, and click the Collection Editor elipsis button as
    indicated below

  • When the Collection Editor opens:
    • Select the second ColumnDefinition in the ListBox on the left
    • Click the Width property Property Marker
    • From the Context Menu, select Reset Value
      • This will change the second column to its default value which is 1*
    • Click the OK button to commit the changes
    • This will effectively split the form into two proportionally spaced columns that are of equal width

  • The form now has two equal sized Star sized columns.

  • Click
    the design surface outside the Window to select the Window. Notice the
    Grid’s rail adorners are no longer visible and the Window resize
    adorners are now visible.
  • Resize the Window to 600 x 300 as pictured below.

  • Marquee select the first four Labels and TextBoxes and release the mouse button

  • Right click the selected controls and select Copy from the Context Menu
  • Right click the selected controls and select Paste from the Content Menu
  • The eight controls will remain selected; now drag them into position to the right colomn

  • Use the text baseline snap line to vertically align the controls as pictured below

  • Change the Content property on the Label controls on the right to the values below
  • Marquee select the two Buttons, drag and drop them to the below location

  • Select
    the Window by clicking the design surface outside the Window boundary.
    Using the lower left corner resize adorner, resize the Window smaller
    and larger. Notice that the two columns stay the same size and the
    controls size to the column.

Content Based Layout 

The
purpose of the article is to help Windows Forms developer’s make the
transition to WPF or Silverlight. In the above walk-through we guided
you through creating a WPF or Silverlight form using familiar form
design techniques you used in Windows Forms.

Now that you have
an understanding of control placement and some Grid concepts, let’s
walk-through building a content based layout form. This type of form is
still very easy to build, it leverages more features of the Grid control
and providing a layout that conforms to content as the size of that
content changes at design or run-time; for example a globalized
application when a different language is being used.

Again, in
this next section we’ll demonstrate how to easily create a form that
uses content base layout instead of absolute positioning while at the
same time leveraging layout techniques that are familiar to you.

The
strategy of this technique is to quickly layout, name and set the text
values for your controls. When dragging a control from the ToolBox we
are only concerned with positioning the control near where you want it.
From the below image you can see I’ve paid very little attention to size
or positioning.

Step One – Quick Layout

  • Increase the size of the Window; this will give you more room to drag and drop controls with less precision
  • Drag and drop controls onto the design surface then set their Content property for Labels
    • Remember, you don’t need to worry about exact positioning or sizing, now. Just lay the controls out very quickly
  • We will add the two RadioButtons and two Buttons later on

Step Two – Create Rows

  • Select the root Grid control by clicking inside its boundary

  • Create your first Grid row by clicking the left Grid Rail Adorner as pictured below

  • Repeat creating the Grid rows so that your form looks like the below image

Step Three – Create Columns

  • Create the columns by clicking the top Grid Rail Adorner as pictured below

Step Four – Auto Size Controls

  • With
    the root Grid selected, press CTRL+A to select all child controls of
    the Grid. Optionally, you can also marquee select controls.

  • Right click on one of the selected controls, from the Context Menu select, Reset Layout, All

  • Your form should look similar to the below image
  • What has happened to each control is:
    • Margin reset to default value, 0
    • VerticalAlignment reset to default, Stretch
    • HorizontalAlignment reset to default, Stretch
    • Size reset to default, Auto
  • Notice how each control consumes the full space allocated to it by its container cell.

Step Five – Auto Size Rows

  • Hover the mouse over the left Grid Rail Adorner near the numbers, a Grid Row size selector will appear
  • Click Auto
  • Repeat for each row except the last row

  • Your form should now look like the below image. You can now see why we didn’t spend much time during the initial layout.
    • The bottom row is Star sized. In this form it will consume all the remaining vertical space.

Step Six – Auto Size the First Column

  • Hover the mouse over the top Grid Rail Adorner near the numbers, a Grid Column size selector will appear
  • Click Auto
  • By
    auto sizing the first column we are allowing the text of the Label
    controls to grow at run-time or design-time based on a font, font size
    or language change.
    • Another option is to
      provide a fixed width of reasonable value, replace the Label controls
      with TextBlocks and enable text wrapping. Since the rows are auto sized,
      if the text does wrap the row size will automatically be increased to
      accommodate the increase is height.

Step Seven – Margins

  • Select all child Grid controls using CTRL+A
  • Notice the Properties Window
    • Top red arrow – multiple objects are now selected
    • Middle red arrow – enter "mar" in the Search Box
    • Bottom red arrow – enter "6" for the Margin
  • On the design surface, all of the controls all have a Margin of 6.

Step Eight – RadioButtons

  • Click the StackPanel icon in the ToolBox, and then draw the StackPanel in the column next to the Gender Label.

  • Use the Reset Layout feature for the StackPanel

  • Using the Properties Window, set the following properties:
    • Orientation to Horizontal
    • Margin to 6

  • With the StackPanel selected double click on the RadioButton icon in the ToolBox to create the first RadioButton
  • Repeat the double click action to create the second RadioButton.
  • Using the Properties Window set the following RadioButton properties :
    • Content property for each RadioButton to the appropriate text (Male, Female)
    • Reset Height property as pictured below

    • VerticalAlignment to Center
    • Female RadioButton, set the Margin property to 12,0,0,0
  • Your form should now look like the below image

Step Nine – Add the Buttons

We will now use the Grid SharedSizeScope feature you learned about in the WPF & Silverlight Layout Controls article.

This
feature enables us to ensure that the Button controls will be the same
size, even if the text of one button is shorter/longer than the other
Button.

  • Draw a new Grid in the row below the RadioButtons
  • Add a column to that Grid near the middle of the Grid
  • Add a Button control to each Grid cell as in the below picture

  • With
    the new Grid selected on the design surface, switch to XAML view.
    Notice that the same Grid is selected in the XAML Editor for you.
  • Add the attached property, Grid.IsSharedSizedScope and set its value to True.
    • This attached property is currently not available in the Properties Window so we need to use the XAML Editor.

  • Switch back to Design view and select the new Grid again.
  • Using the Properties Window, locate the ColumnDefinitions property and click the ellipsis button to open the Collection Editor.

  • For both columns, set the Width to Auto and the SharedSizeGroup to buttons
  • Click OK to close the dialog and commit the changes

  • On the design surface, select both Button controls in the new Grid
  • Using the Properties Window, set the six properties indicated by the red arrows
    • Setting the Button Padding property provides nice internal spacing between the Button’s text and border.
  • Your form will now look like the below image

Information

What is the above degenerate area?

The degenerate area (or degenerate zone) is an area of the Grid that remains after the last column or row.

The
above Grid is 300px wide, but its two columns are Auto sized only
taking up about 110px total; the remaining 190px area is the degenerate
area.

Notice the
top Grid Rail Adorner for the degenerate area does not have a number on
it. This is because there really is no column there. The missing number
on a Grid Rail Adorner for a row or column is a visual indicator that
that row or column does not exists.

  • On the design surface, select the new Grid
  • Using the Properties Window, set the five properties indicated by the red arrows
  • Your form will now look like the below image

Information

The
reason we right aligned the above Grid is to anchor the Grid (and the
child buttons) to the right edge of the form. If the form is resized,
the Grid will stay anchored to the right edge.

  • Using the Properties Window, selected each Button and set the Content property adoringly
    • Notice the buttons have the same width. This provides a nice clean look.
  • Resize form to desired size.

Tip

This is an auto sized form. Notice when you resize the forms width, the TextBoxes resize with the form.

At your option, you could set a fixed width for the TextBoxes.

At
your option you could also set the MinWidth property on the Window or
TextBoxes to prevent the user from resizing the dialog too small.

Review 

In this short article we have learned that:

  • Form layout skills learned in Windows Forms transfer to WPF and Silverlight
  • Absolute positioning can be used in WPF or Silverlight applications
  • Adopting content based layout in WPF or Silverlight can easily be achieved by following a simple workflow:
    • Roughly layout the form
    • Add Grid rows and columns
    • Resize Grid child controls
    • Set appropriate Margins for child controls
    • Add additional controls, etc.

Comments 

Microsoft
values your opinion about our products and documentation. In addition
to your general feedback it is very helpful to understand:

  • How the above features enable your workflow
  • What is missing from the above features that would be helpful to you

Thank you for your feedback and have a great day,

Karl Shifflett
Expression Team

This entry was posted in UI. Bookmark the permalink.

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s