Layout and Panels Tutorial

This tutorial is dedicated to show how GUI elements get positioned and sized in relation to their container. Layout is a critical component of an application's usability on a wide range of devices. Also we will discover the variety of containers available to use in NoesisGUI.

Element Positioning

The FrameworkElement class exposes several properties that are used to precisely position child elements. This topic discusses four of the most important properties: HorizontalAlignment, Margin, Padding, and VerticalAlignment. The effects of these properties are important to understand, because they provide the basis for controlling the position of elements in NoesisGUI.

Alignment

Alignment determines how child elements are placed within the allocated space of the parent element. In other words, it determines the position on the space it was provided to the element. There are two types of alignment: HorizontalAlignment and VerticalAlignment.

HorizontalAlignment

The HorizontalAlignment property declares the horizontal alignment characteristics to apply to child elements. The following table shows each of the possible values of the HorizontalAlignment property.

Member

Description

Left

Child elements are aligned to the left of the parent element's allocated layout space.

Center

Child elements are aligned to the center of the parent element's allocated layout space.

Right

Child elements are aligned to the center of the parent element's allocated layout space.

Margin

Margin determines the distance between one control to the boundary of the cell where it is placed. It can be uniform or you can specify the value of all its sides. For instance, Margin="20" means that the properties left, top, right and bottom are all set to 20. Margin="20,10,0,10" assigns a left margin of 20, a top margin of 10, a right margin of 0 and a bottom one of 10.

Containers

In NoesisGUI interfaces are built combining containers and controls that form a hierarchical visual tree. There are four kind of containers: Content Containers, Items Containers, Decorators and Panels.

Content Containers

ContentControl

Controls that hold a single child Content. The content can be a string, an object or even another UIElement. Examples: Button, Label and ToolTip.

Viewbox

Viewbox provides an easy mechanism to scale arbitrary content within a given space. By default, Viewbox stretches in both dimensions to fill the shape given to it (like most controls). But it also has a Stretch property to control how its single child gets scaled within its bounds. A second property of Viewbox, StretchDirection, controls whether you only want to use it to shrink content or enlarge content (as opposed to doing either).

NOTE

Viewbox is the ideal container to make your application Resolution Independent

Panels

NoesisGUI contains six main built-in panels who are, in increasing order of complexity and usefulness: Canvas, StackPanel, UniformGrid, WrapPanel, DockPanel and Grid.

Canvas

Canvas is a special layout panel that distributes elements with absolute position, that is, using x and y coordinates. When used within a canvas, an element is not restricted to anything, it can overlaps other controls. The rendering order is determined by how the elements are declared in the XAML. This sequence can be altered by using the Panel.ZIndex property.

Canvases do not enforce any restriction to their elements. So the width and height of individual elements must be specified. You can use the attached properties Canvas.Left or Canvas.Right and Canvas.Top or Canvas.Bottom to specify the distance to the chosen side of the parent.

StackPanel

StackPanel is a container where child elements are arranged in a single line that is oriented horizontally or vertically. The orientation is defined by the property Orientation which can take two valid values:

Vertical: This is the default orientation. Child items are placed vertically one after another from top to bottom.

Horizontal: Here the items are placed from left to right one after another.

UniformGrid

UniformGrid control provides a similar layout to that given by the Grid layout control. Its child controls are organized into a tabular structure of rows and columns. Unlike the Grid control, you don't have fine-grained control of the layout. The column widths and row heights cannot be modified. These sizes are set automatically to ensure that all columns are the same width and all rows are of an equal height. In addition, where the Grid control permits you to specify a cell position for each child, the UniformGrid does not.

WrapPanel

WrapPanel is almost similar to StackPanel, but it produces a new line when it reaches the edge of the panel. So if you resize the WrapPanel, the content will be automatically wrapped to the new line. Thus WrapPanel has additional flexibility to wrap elements when space matters.

Another difference is that WrapPanel determines the size based on the size of the content rather than considering it infinity as StackPanel does. You can also specify the size of the layout partition that is reserved by the WrapPanel for each child element by using the properties ItemWidth and ItemHeight. These properties take precedence over element's own width and height.

DockPanel

DockPanel is the most widely used control to determine the layout of an application. It uses the attached property DockPanel.Dock to determine the position of each contained element. Valid values are Top, Bottom, Left and Right.

If the height or the width of the contained element it is not specified it will take the whole available area.

As shown, the Dock property needs to be explicitly mentioned on each individual element. The sequence of declarations also plays a vital role. If you set the dock of two elements in a row to "Top" it means that those elements will appear vertically stacked.

A property called LastChildFill makes the remaining space to be filled with the last element. You can set it to false if you don't need it.

Grid

Grid is one of the most powerful panels. It can be used to form a table that fills the available space. You can use the properties RowDefinitions and ColumnDefinitions to define the rows and columns of the Grid. To size a cell the properties Height and Width of RowDefinition and ColumnDefinition respectively are used. Valid values are:

Auto: The size is determined by the element you place within the table cell.

Star: When you use star, it means the measurement will be done using a ratio. "2*" means double of "1*". So if you want to make two columns in 2:1 ratio you set the width to "2*" and "1*" respectively. The default value is a "1*".

Absolute: You can also specify the absolute value of height and width in pixels.

Cell size can be restricted using MinHeight/MaxHeight for rows and MinWidth/MaxWidth for columns. These properties admit absolute values only.

To place elements inside the table cells the attached properties Grid.Row and Grid.Column are used. An element can also span a total number of rows and columns using the attached properties Grid.RowSpan and Grid.ColSpan respectively.