WPF: Canvas Panel

Wednesday, 29 August 2012


The Canvas is the most basic layout panel in WPF. It's child elements are positioned by explicit coordinates. The coordinates can be specified relative to any side of the panel usind the Canvas.Left, Canvas.Top, Canvas.Bottom and Canvas.Right attached properties.
The panel is typically used to group 2D graphic elements together and not to layout user interface elements. This is important because specifing absolute coordinates brings you in trouble when you begin to resize, scale or localize your application. People coming from WinForms are familiar with this kind of layout - but it's not a good practice in WPF.
 

Override the Z-Order of Elements
Normally the Z-Order of elements inside a canvas is specified by the order in XAML. But you can override the natural Z-Order by explicity defining a Canvas.ZIndex on the element.
 


WPF: Grid Panel


 

The grid is a layout panel that arranges its child controls in a tabular structure of rows and columns. Its functionality is similar to the HTML table but more flexible. A cell can contain multiple controls, they can span over multiple cells and even overlap themselves.
The resize behaviour of the controls is defined by the HorizontalAlignment and VerticalAlignment properties who define the anchors. The distance between the anchor and the grid line is specified by the margin of the control

Define Rows and Columns

The grid has one row and column by default. To create additional rows and columns, you have to add RowDefinition items to the RowDefinitions collection and ColumnDefinition items to the ColumnDefinitions collection. The following example shows a grid with three rows and two columns.
The size can be specified as an absolute amount of logical units, as a percentage value or automatically.
Fixed
Fixed size of logical units (1/96 inch)
Auto
Takes as much space as needed by the contained control
Star (*)
Takes as much space as available (after filling all auto and fixed sized columns), proportionally divided over all star-sized columns. So 3*/5* means the same as 30*/50*. Remember that star-sizing does not work if the grid size is calculated based on its content.
 
 

How to add controls to the grid

To add controls to the grid layout panel just put the declaration between the opening and closing tags of the Grid. Keep in mind that the row- and columndefinitions must precced any definition of child controls.
The grid layout panel provides the two attached properties Grid.Column and Grid.Row to define the location of the control.

Resizable columns or rows


WPF provides a control called the GridSplitter. This control is added like any other control to a cell of the grid. The special thing is that is grabs itself the nearest gridline to change its width or height when you drag this control around.

 
The best way to align a grid splitter is to place it in its own auto-sized column. Doing it this way prevents overlapping to adjacent cells. To ensure that the grid splitter changes the size of the previous and next cell you have to set the ResizeBehavior to PreviousAndNext.
The splitter normally recognizes the resize direction according to the ratio between its height and width. But if you like you can also manually set the ResizeDirection to Columns or Rows.
<GridSplitter ResizeDirection="Columns"/>
 

How to share the width of a column over multiple grids

The shared size feature of the grid layout allows it to synchronize the width of columns over multiple grids. The feature is very useful if you want to realize a multi-column listview by using a grid as layout panel within the data template. Because each item contains its own grid, the columns will not have the same width.
By setting the attached property Grid.IsSharedSizeScope to true on a parent element you define a scope within the column-widths are shared.
To synchronize the width of two columndefinitions, set the SharedSizeGroup to the same name.
 
<ItemsControl Grid.IsSharedSizeScope="True" >
  <ItemsControl.ItemTemplate> 
    <DataTemplate>
      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition SharedSizeGroup="FirstColumn" Width="Auto"/>
          <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <TextBlock Text="{Binding Path=Key}" TextWrapping="Wrap"/>
        <TextBlock Text="{Binding Path=Value}" Grid.Column="1" TextWrapping="Wrap"/>
      </Grid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>
 
 

Useful Hints

Columns and rows that participate in size-sharing do not respect Star sizing. In the size-sharing scenario, Star sizing is treated as Auto. Since TextWrapping on TextBlocks within an SharedSize column does not work you can exclude your last column from the shared size. This often helps to resolve the problem.

Using GridLenghts from code

If you want to add columns or rows by code, you can use the GridLength class to define the differenz types of sizes.

Auto sized
GridLength.Auto
Star sized
new GridLength(1,GridUnitType.Star)
Fixed size
new GridLength(100,GridUnitType.Pixel)
Grid grid = new Grid();
 
ColumnDefinition col1 = new ColumnDefinition();
col1.Width = GridLength.Auto;
ColumnDefinition col2 = new ColumnDefinition();
col2.Width = new GridLength(1,GridUnitType.Star);
 
grid.ColumnDefinitions.Add(col1);
grid.ColumnDefinitions.Add(col2);
 

WPF: Wrap Panel


Introduction
The wrap panel is similar to the StackPanel but it does not just stack all child elements to one row, it wraps them to new lines if no space is left. The Orientation can be set to Horizontal or Vertical.
The WrapPanel can be used to arrange tabs of a tab control, menu items in a toolbar or items in an Windows Explorer like list. The WrapPanel is often used with items of the same size, but its not a requirement.
 

WPF: Dock Panel




Introduction
The dock panel is a layout panel, that provides an easy docking of elements to the left, right, top, bottom or center of the panel. The dock side of an element is defined by the attached property DockPanel.Dock. To dock an element to the center of the panel, it must be the last child of the panel and the LastChildFill property must be set to true.




Multiple elements on one side
The dock panel layout supports multiple elements on one side. Just add two or more elements with the same dock side. The panel simply stacks them.

Change the stacking order
The order of the elements matters. It determines the alignment of the elements. The first elements gets the whole width or height. The following elements get the remaining space.