Consider the document Properties dialog from Internet Explorer shown in Figure 3-8. Notice how the main area of the form is arranged as two columns. The column on the left contains labels, and the column in the middle contains information.
Figure 3-8. Document Properties dialog
Achieving this kind of layout with any of the panels we've looked at so far is difficult, because they are not designed with two-dimensional alignment in mind. We could try to use nesting—Example 3-6 shows a vertical StackPanel with three rows, each with a horizontal StackPanel.
<StackPanel Orientation="Vertical" Background="Beige"> <StackPanel Orientation="Horizontal"> <TextBlock>Protocol:</TextBlock> <TextBlock>HyperText Transfer Protocol</TextBlock> </StackPanel>
<StackPanel Orientation="Horizontal"> <TextBlock>Type:</TextBlock> <TextBlock>HTML Document</TextBlock> </StackPanel>
<StackPanel Orientation="Horizontal"> <TextBlock>Connection:</TextBlock> <TextBlock>Not Encrypted</TextBlock> </StackPanel> </StackPanel>
The result, shown in Figure 3-9, is not what we want at all. Each row has been arranged independently, so we don't get the two columns we were hoping for.
Protocol:HyperText Transfer Protocol Type:HTML Document ConnectiomNot Encrypted
The Grid panel solves this problem. Rather than working a single row or a single column at a time, it aligns all elements into a grid that covers the whole area of the panel. This allows consistent positioning from one row to the next. Example 3-7 shows the same elements as Example 3-6, but arranged with a Grid rather than nested StackPanel elements.
Example 3-7. Grid layout
ShowGridLines="True"> <!-- ShowGridLines for testing only --> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions>
Example 3-7. Grid layout (continued)
<TextBlock Grid.Column="0" Grid.Row="0">Protocol:</TextBlock>
<TextBlock Grid.Column="1" Grid.Row="0">HyperText Transfer Protocol</TextBlock>
<TextBlock Grid.Column="0" Grid.Row="1">Type:</TextBlock>
<TextBlock Grid.Column="1" Grid.Row="1">HTML Document</TextBlock>
<TextBlock Grid.Column="0" Grid.Row="2">Connection:</TextBlock>
<TextBlock Grid.Column="1" Grid.Row="2">Not encrypted</TextBlock>
The Grid needs to know how many columns and rows we require, and we indicate this by specifying a series of ColumnDefinition and RowDefinition elements at the start. This may seem rather verbose—a simple pair of properties on the Grid itself might seem like a simpler solution. However, you will often need to control the characteristics of each column and row independently, so in practice, it makes sense to have elements representing them.
Notice that each element in the grid has its column and row specified explicitly using attached properties. This is mandatory—without these, everything ends up in column 0, row 0. (Grid uses a zero-based numbering scheme, so 0,0 corresponds to the top-left corner.)
Grid, Element Order, and Z Order
You might be wondering why the Grid doesn't simply put items into the grid in the order in which they appear; this would remove the need for the Grid.Row and Grid.Column attached properties. However, grids do not necessarily have exactly one element per cell. Grid cells can be empty. If the grid's children simply filled the cells in order, you would need to provide placeholders of some kind to indicate blank cells. But because elements indicate their grid position, you can leave cells empty simply by providing no content for those cells.
Elements may span multiple cells, by using the Grid.RowSpan and Grid.ColumnSpan attached properties.
Cells can also contain multiple elements. In this case, the order in which the relevant elements are listed in the markup determines which appears "on top." Elements that appear later in the document are drawn over those that appear earlier. The order in which overlapping elements are drawn is usually referred to as the Z order. This is because the x- and y-axes are traditionally the ones used for drawing on-screen, so the z-axis, representing the third dimension, "sticks out" of the screen. This makes it the logical axis to represent how overlapping elements stack up on top of one another. In general, panels that allow their children to overlap (e.g., Grid and Canvas) rely on the order in which elements appear in the XAML to determine the Z order. However, you can override this: the attached Panel.ZIndex property allows the Z order to be specified explicitly.
Figure 3-10 shows the result of Example 3-7. This figure has lines showing the grid outline, because we enabled the ShowGridLines property. You would not normally do this on a finalized design—this feature is intended to make it easy to see how the Grid has divided up the available space. With grid lines displayed, it is clear that the Grid has made all the columns the same width, and all the rows the same height.
Protocol: iHyperText Transfer Protocol ConnectionjNot encrypted
What may not be obvious from Figure 3-10 is that each element has been given the full available cell space. It doesn't show here because a TextBlock looks only as large as the text it shows. But the behavior is somewhat similar to a StackPanel—each element's width is as wide as its containing column, and its height is that of its containing row. As always, you can use HorizontalAlignment and VerticalAlignment to determine what elements do with excess space.
This default "one size fits all" behavior is useful when you want all the items in the grid to be the same size, but it's not what we want here. It would make more sense for the column on the left to be wide enough to contain the labels, and for the column on the right to be allocated the remaining space. Fortunately, the Grid provides a variety of options for managing column width and row height.
Was this article helpful?
What you need to know about… Project Management Made Easy! Project management consists of more than just a large building project and can encompass small projects as well. No matter what the size of your project, you need to have some sort of project management. How you manage your project has everything to do with its outcome.