|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Services
Chapters
Feature Zones
|
Table of contents
IntroductionThis is the second article in an introductory series about the Windows Presentation Foundation. In the previous article, we discussed XAML and how it is used in WPF application development. This article shifts focus to WPF's rich support for layout panels, and how they are used in the WPF Horse Race demo application (which is available for download at the top of the first article in this series). This article is not intended to provide an encyclopedic review of the entire layout system in WPF. The Windows SDK documentation provides ample material on how to use and extend the WPF layout system, so there is no point in repeating it. Instead, we will briefly cover the basics and then examine how the WPF Horse Race application makes use of the two most common layout panels, Grid and StackPanel. BackgroundTraditional desktop application user interface development is mostly based on absolute positioning of visual elements, namely setting properties on controls to affect their location and size. There are some higher-level concepts one can use to make it easier to create UIs that adapt to a changing Window size, such as docking and anchoring of controls to their respective containers. However, as of Windows Forms 2.0 there was still much to be desired in the realm of automatic UI layout. WPF addresses those issues very well, in many cases by borrowing some of the better layout concepts from the world of HTML. Layout via panelsThe Panel class is the abstract base for all layout panels in WPF. It has a All but one of the Panel subclasses provide automatic positioning of its children; Canvas being the exception to that rule. This basically means that as the size of the Window changes, panels automatically update the location of their child elements. Some panels, such as DockPanel and Grid, can also affect the display size of their child elements. That behavior is useful when you want visual elements to occupy as much screen space as possible, such as when displaying photographs or a line chart. If you are interested in learning about all of the built-in Attached layout settingsThe WPF architects decided that since the layout system is extensible (i.e. you can subclass This problem was solved by introducing attached properties into the WPF framework. An attached property can be set on any object; it does not have to expose the property being set. For example: <DockPanel>
<Button DockPanel.Dock="Left">Alf Was Here</Button>
</DockPanel>
The XAML seen above puts a For more information about how attached properties work refer to the pages mentioned in the External links section at the bottom of this article. In the next section, we will see attached properties in action. How the WPF Horse Race uses panelsThe WPF Horse Race explicitly uses two layout panels: Let's take a look at a simplified version of the main Window's XAML file: <Window>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="Resources/Background.jpg" Opacity="0.25" />
</Grid.Background>
<Grid.RowDefinitions>
<!-- The top row is for the race track. -->
<RowDefinition Height="*" />
<!-- The bottom row is for the command strip. -->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- The 'Race Track' area. -->
<ItemsControl Grid.Row="0" ... />
<!-- The 'Command Strip' area -->
<Border Grid.Row="1">
<Grid>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Margin="10,4">Rotation: </TextBlock>
<Slider ... />
<TextBlock ... />
<TextBlock> degrees</TextBlock>
</StackPanel>
<TextBlock HorizontalAlignment="Right" Margin="10,4">
<Hyperlink>Start new race</Hyperlink>
</TextBlock>
</Grid>
</Border>
</Grid>
</Window>
The XAML seen above contains two
The main layoutThe outermost <Grid.RowDefinitions>
<!-- The top row is for the race track. -->
<RowDefinition Height="*" />
<!-- The bottom row is for the command strip. -->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
The first row's Notice that the row heights are not explicitly set to a numeric value. The Next we can see how to indicate in which row we want visual elements to be placed. <!-- The 'Race Track' area. -->
<ItemsControl Grid.Row="0" ... />
<!-- The 'Command Strip' area -->
<Border Grid.Row="1">...</Border>
The The command strip areaReferring back to the diagram seen above, we can now venture into the nested panels seen toward the bottom of the UI. Here is the XAML which describes that "command strip" area: <Border Grid.Row="1">
<Grid>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center">
<TextBlock Margin="10,4">Rotation: </TextBlock>
<Slider ... />
<TextBlock ... />
<TextBlock> degrees</TextBlock>
</StackPanel>
<TextBlock HorizontalAlignment="Right" Margin="10,4">
<Hyperlink>Start new race</Hyperlink>
</TextBlock>
</Grid>
</Border>
That abridged XAML results in the following visual entity: The entire command strip area is contained within a The The Positioning elements within a panelThere are two common ways to fine-tune the location of an element within a panel. One way is to set the element's Margin property and the other is to set its HorizontalAlignment and/or VerticalAlignment properties. We can see both of those techniques put to use on the <TextBlock HorizontalAlignment="Right" Margin="10,4">
<Hyperlink>Start new race</Hyperlink>
</TextBlock>
Setting the The net effect of those two property settings is that the External linksHistory
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||