The Grid control is one of the more powerful container controls provided by WPF. It divides its area into rows and columns that can contain child controls.
You define the Grid's row and column sizes by setting its Grid.RowDefinitions
property elements. The Grid.RowDefinitions
element should contain RowDefinition
objects that define the rows' heights, while the Grid.ColumnDefinitions
element should contain ColumnDefinition
objects that define the columns' widths.
The real layout power of the Grid occurs because you don't need absolute values. You can set a height or width to a numeric pixel value or you can use a "star" syntax that includes a number followed by an asterisk. After subtracting any space reserved by explicit pixel values, the control divides its remaining space among the "star" rows/columns by calculating a weighted average of their numeric values.
For example, if one row has height 1*
and another has height 2*
, then the first row gets 1/(1+2) = 1/3 of the available height and the second row gets 2/(1+2) = 2/3 of the available height.
After you define row and column sizes, a Grid's child can use Grid.Row
attached properties to indicate which row and column should hold it. You can use the Grid.RowSpan
properties to let a child cover more than one row or column.
The following code fragment shows how the UsesDirectX
example shown in Figure 1
defines the Grid inside the program's Button. The star syntax makes the rows and columns have equal heights and widths. To keep the code short, I've omitted some of the Grid's children. Download the example
to see the complete code.
<Grid Width="300" Height="300">
<Image Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"
Stretch="Fill" Source="fractal_surface.gif" Opacity="0.6"/>
... other items omitted ...
<Image Grid.Row="2" Grid.Column="1" Source="Network.jpg"/>
<Image Grid.Row="2" Grid.Column="2" Source="Map.jpg"/>
A GridSplitter lets users resize a Grid's rows and columns at run time. For example to let a user resize two adjacent columns, place a GridSplitter in the left column. Use the Grid.RowSpan
property if necessary so the GridSplitter spans all the Grid's rows vertically. Set the control's Width
so it's big enough for the user to grab. Now at run time the user can click and drag the control to resize the Grid's columns.
|Author's Note: Tip: Be sure to define the GridSplitter in the code after any other controls in the same column so it sits on top of them instead of being hidden behind them.
The following code shows how the GridSplitter in the ControlSamples
program lets users resize the Grid's two columns. In Figure 2
, the GridSplitter is the grayish stripe between the blue "Left" label and the yellow "Right" label.
<Grid Height="50" Margin="0,5,0,0">
<Label Grid.Column="0" Background="LightBlue" Content="Left" />
<GridSplitter Grid.Column="0" Width="5"/>
<Label Grid.Column="1" Background="Yellow" Content="Right"/>
The GroupBox works much like the Windows Forms version. It draws some header text (defined by its Header
property) and a border around its single child.
As in Windows Forms, the GroupBox also defines a RadioButton group, so clicking one RadioButton in the GroupBox deselects the other RadioButtons in the GroupBox. (Note that in WPF all
container controls define RadioButton groups, not just the GroupBox.)
The following code shows how the program ControlSamples
defines its GroupBox.
<GroupBox Header="GroupBox" Height="80">
<Label Content="This is a Label."/>
<Label Content="Another Label."/>
The Image control displays a picture. This control's most important properties are Source
specifies the path to the image that the control should display. This can be a path to an image inside the program or it can be a URL. The Stretch
property determines how the control stretches the picture to fill the control. This property can take the following values:
- Fill: The picture is stretched to fill the control even if that distorts the picture.
- None: The picture is not stretched but is shown at full size and may be clipped if it won't fit.
- Uniform: The picture is made as large as possible while still fitting within the control without distorting it.
- UniformToFill: The picture is made as large as necessary to fill the entire control without distorting it. Unless the picture and the control have the same width-to-height ratio, part of the picture will be clipped.
Here's the Image control definition from the ControlSamples
<Image Stretch="Uniform" Source="fractal_surface.gif"/>
A Label simply displays text that users can see but cannot modify or select. Normally you set the Label's text using the control's Content
property as in the following code:
<Label Content="Choice 1"/>
However, you can place other objects inside a Label to give it more complex content.
A Line control draws a simple line segment. Its X1
, and Y2
properties specify the coordinates of the line's end points. Its stroke properties (Stroke
, and so forth) determine the line's appearance.
Like its Windows Forms counterpart, the ListBox displays a list of choices that the user can select. The WPF version, however, can easily hold text, images, and more complex items that are hard to handle with the Windows Forms ListBox.
The ListBox should contain ListBoxItem objects that define the items users can select. If an item contains only simple text, you can set it with the ListBoxItem's Content
property determines how the user can select items. This property can take the values Single
(users can select only one item), Multiple
(users can select multiple items; clicking an item toggles whether it is selected), or Extended
(users can select multiple items using Click, Shift-Click, and Ctrl-Click).
When the SelectionMode
is set to Single
, you can use the control's SelectedIndex
, and SelectedValue
properties to set or retrieve the currently selected item. For the other selection modes, set the ListBoxItem objects' IsSelected
property to True
to indicate which items are selected.
Here's the ListBox definition for the ControlSamples
<Image Source="Apple.jpg" Height="30" Width="30"/>
<Image Source="Banana.jpg" Height="30" Width="30"/>
<Image Source="Cherry.jpg" Height="30" Width="30"/>
The ListView displays a set of child objects in several different ways. This is one of the more complicated WPF controls and a complete discussion of it won't fit here, but I'll cover the details in a future article.
Basically, though, the ListView contains View objects that define different views of the data. Typically a View contains a GridView that defines display columns much like those used by the Windows Forms ListView.
You use data binding to tell the GridView how to pull data out of the objects that you want to display. For a set of Book objects, for example, you might have the view display an object's Title
, and Year
properties in three columns. You would create a collection of Book objects and attach it to the ListView.
You can define multiple Views to show the data in different ways.
The MediaElement control plays a video or audio file. Set the control's Source
property to determine the file the control will play. The UsesDirectX
program displays its video file as follows:
The control provides several useful properties and methods that let your code control it. These include the intuitively named Pause
, and Volume
Menu and MenuItem
The Menu control builds a menu. It contains MenuItem controls that provide the menu's commands.
The MenuItem's Header
property, which normally contains plain text, determines what the user sees in the menu. When users select a MenuItem, it fires its Click
A MenuItem can contain other MenuItems to make submenus.
Unfortunately, a MenuItem does not automatically appear at the top of a Window and it does not automatically reserve space for itself. If you simply put a Menu on a Window with other controls, it might end up in a strange position overlapping those controls.
Probably the easiest way to handle this is to give the Window a DockPanel and set the Menu's DockPanel.Dock
property to Top.