|
|||||||||||||||||||||
|
|||||||||||||||||||||
|
Announcements
Services
Chapters
Feature Zones
|
Table of contents
IntroductionThis is the fifth article in an introductory series about the Windows Presentation Foundation. In the previous article we examined data templates and triggers to see how the rendering of data objects can be described in XAML. In this article we examine styles, 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). Just like the other articles in this series, this article does not cover its subject matter in exhaustive detail. Instead we will examine just enough of the basics so that we can see how those features are put to use in the demo app. If you want to learn more about how styles can be used, refer to the External links section for additional information. BackgroundWPF borrows many concepts from both the Web and desktop programming worlds. The separation of user interface layout from behavior (i.e. XAML vs. code-behind) is a tip of the hat to ASP.NET. The extensive set of event-driven APIs for detailed control over user interaction is reminiscent of the Windows Forms programming model. WPF can be thought of as a distillation of the best features found in various UI platforms, plus a wide range of new features as well. One major contribution made to WPF by the world of Web development was the concept of styles. Styling in WPF is somewhat similar to how Cascading Style Sheets (CSS) is used by Web developers. The basic idea of styling in WPF is that you can define a Style vs. themeBefore we start looking into styles, it is important to draw a distinction between styles and themes. Operating systems have "themes", WPF applications have "styles". Themes are an OS-level concept: such as the blue, green, and silver themes seen in Windows XP, or the Aero theme in Vista. WPF applications automatically detect the current OS theme and use that color scheme wherever possible, and can even programmatically choose which theme to use. A style exists only within one WPF application, or just one Window in a WPF application, or even just one portion of a Window for that matter. Styles cannot be applied to anything outside of the WPF application in which they exist, nor can they be applied to any WinForms controls hosted within a WPF Window. For more information about theme support in WPF, refer to the External links section at the end of this article. The Style classThe entire styling infrastructure in WPF is based on the Style class. It has a relatively small set of public members, which makes it easy to grasp how styling works. Instances of the Here are some of the properties of
The styles created in the WPF Horse Race demo application are very simple. There are other common properties of the
A Without stylesIf WPF did not provide a way to stylize elements, you would have to be out of your mind to even consider creating a distinctive, branded look and feel for an application's user interface. To create a visual consistency across all Windows in an application would quickly turn into a maintenance nightmare, especially once changes needed to be made to certain aspects of the visual style. For example, consider the following XAML: <Border BorderBrush="Black" BorderThickness="2">
<StackPanel>
<TextBlock Background="Tan" Margin="2,4">Bike</TextBlock>
<TextBlock Background="Tan" Margin="2,4">Car</TextBlock>
<TextBlock Background="Tan" Margin="2,4">Truck</TextBlock>
</StackPanel>
</Border>
That simple markup results in something which looks like this:
Suppose that the application we are building used to have a rule that If our application only had the three <Border BorderBrush="Black" BorderThickness="2" Margin="10">
<StackPanel>
<TextBlock Background="LightGray" Margin="2,4">Bike</TextBlock>
<TextBlock Background="LightGray" Margin="2,4">Car</TextBlock>
<TextBlock Background="LightGray" Margin="2,4">Truck</TextBlock>
</StackPanel>
</Border>
But if our application happens to contain hundreds or even thousands of With stylesFortunately there is an easy way to set properties on any number of elements: "styles". Let's see how a <Border BorderBrush="Black" BorderThickness="2">
<StackPanel>
<StackPanel.Resources>
<Style x:Key="TxtBlkStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Margin" Value="2,4" />
</Style>
</StackPanel.Resources>
<TextBlock Style="{StaticResource TxtBlkStyle}">Bike</TextBlock>
<TextBlock Style="{StaticResource TxtBlkStyle}">Car</TextBlock>
<TextBlock Style="{StaticResource TxtBlkStyle}">Truck</TextBlock>
</StackPanel>
</Border>
The XAML seen above creates a
It turns out that there's an even easier way to accomplish this task. If you do not give a <Border BorderBrush="Black" BorderThickness="2">
<StackPanel>
<StackPanel.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Margin" Value="2,4" />
</Style>
</StackPanel.Resources>
<TextBlock>Bike</TextBlock>
<TextBlock>Car</TextBlock>
<TextBlock>Truck</TextBlock>
</StackPanel>
</Border>
The solutions seen so far do not really solve the overall problem. If we want the entire application to contain light gray <!-- App.xaml -->
<Application x:Class="WPF_Test.MyApp"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml"
>
<Application.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Background" Value="LightGray" />
<Setter Property="Margin" Value="2,4" />
</Style>
</Application.Resources>
</Application>
<!--Somewhere inside of SomeWindow.xaml -->
<Border BorderBrush="Black" BorderThickness="2">
<StackPanel>
<TextBlock>Bike</TextBlock>
<TextBlock>Car</TextBlock>
<TextBlock>Truck</TextBlock>
</StackPanel>
</Border>
Since the How the WPF Horse Race uses stylesThe WPF Horse Race demo application creates two Race pit border styleIf the
With the
In the RacePitBorderStyle.xaml file, you will find a <!-- This resource dictionary contains the Style applied to
each horse's race pit. -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Style x:Key="RacePitBorderStyle" TargetType="Border">
<Style.Resources>
<LinearGradientBrush x:Key="BackBrush"
StartPoint="0.5,0" EndPoint="0.5,1"
>
<GradientStop Color="#88000000" Offset="0.1" />
<GradientStop Color="#CC000000" Offset="0.9" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="BorderBrush"
StartPoint="0.5,0" EndPoint="0.5,1"
>
<GradientStop Color="#18000000" Offset="0.1" />
<GradientStop Color="#08000000" Offset="0.9" />
</LinearGradientBrush>
</Style.Resources>
<Setter Property="Background" Value="{StaticResource BackBrush}"/>
<Setter Property="BorderBrush" Value="{StaticResource BorderBrush}"/>
<Setter Property="BorderThickness" Value="1" />
<Setter Property="CornerRadius" Value="8" />
<Setter Property="Margin" Value="2,4" />
</Style>
</ResourceDictionary>
That <!-- RaceHorseDataTemplate.xaml -->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfHorseRace"
>
<!-- Import the resource dictionary which contains the Style
applied to Border of each horse's "pit". -->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="RacePitBorderStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type local:RaceHorse}">
<Border x:Name="racePit" Style="{StaticResource RacePitBorderStyle}">
<!-- Other elements omitted for clarity. -->
</Border>
</DataTemplate>
</ResourceDictionary>
Command strip text styleThe other <StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<!-- This Style is applied to all TextBlock
elements in the command strip area. -->
<Style TargetType="TextBlock">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="Foreground" Value="#EE000000" />
</Style>
</StackPanel.Resources>
<TextBlock>Rotation: </TextBlock>
<Slider ... />
<TextBlock ... />
<TextBlock> degrees</TextBlock>
</StackPanel>
Notice that this External linksStyles and themes
Styles
Themes
History
| ||||||||||||||||||||