Styles in WPF

DevToolsGuy / Monday, March 4, 2013

Styles are the means using which you can implement a consistent look and behavior in WPF applications. Using styles, you can easily change the visual appearance of a control.

Through styles, you can apply a set of one or more properties, resources, and so on to one or more elements.

Consider a UI screen designed with plenty of controls. The controls belonging to each type, such as TextBox or Button need to look similar for overall consistency. This can be achieved through styles.

The Style element is used to define styles. It has a TargetType attribute specifying the object to which the style will be applied and a Key attribute uniquely identifying the style. A Style element contains one or more Setter elements, each of which has a Property attribute and a Value attribute.

The Property attribute specifies the property that the Setter will change while the Value attribute specifies the property value.

Following are some important points regarding styles:

  • Any element derived from FrameworkElement can have a style applied to it.
  • You must set the TargetType property when you create a Style, failing which, the XAML processor throws an exception.
  • Styles can be defined using either attribute syntax or property element syntax, though the preferred approach is the attribute syntax.
  • A style defined inline instead of in a resource is limited in scope to the containing element. It has no resource key; therefore, you cannot reuse it, even for other elements of the same type.
  • A style defined in a resource is more adaptable and useful, and is strongly recommended.
  • It is invalid to specify more than one value in a single Setter element.
  • If there is more than one setter in the setter collection with the same Property value, the setter that is declared last is used.

 

Examples:

Some examples of defining and applying styles are shown here:

Example 1:

<UserControl.Resources>
<Style x:Key="MyButtonStyle" TargetType="Button">
<Setter Property="FontSize" Value="24" />
</Style>
</UserControl.Resources>
<StackPanel>
<Button Content="Submit" Width="150" Height="60"
Style="{StaticResource MyButtonStyle}" x:Name="btn1"/>
<Button Content="OK" Width="150" Height="60"
Style="{StaticResource MyButtonStyle}" x:Name="btn2"/>
<Button Content="Cancel" Width="150" Height="60"
Style="{StaticResource MyButtonStyle}" x:Name="btn3"/>
<RadioButton Content="Business"></RadioButton>
</StackPanel>

This code defines a style resource named MyButtonStyle that creates a font style that you want to apply to objects of type Button. The Style contains only one Setter element that sets the FontSize property. In the preceding markup, four controls are created within the StackPanel. However, the style is applied only to the Button controls, and not the RadioButton control. This is because of two things: firstly, the TargetType of the style is set to be Button and secondly, the Style property of the Button controls is explicitly set to MyButtonStyle.

Even if you tried applying the MyButtonStyle to the RadioButton control, it will fail because the TargetType of the style is Button.

Example 2:

The following example defines an inline style with a custom linear gradient brush to a button.

<StackPanel>
<Button Height="120" Width="240">
<Button.Style>
<Style>
<Setter Property="Button.Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Color="Pink" Offset="0.75"/>
<GradientStop Color="Black"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<StackPanel>

You can reuse an existing style to create a new style and add additional Setter elements if required. The BasedOn attribute of a Style element enables you to implement this functionality. Inherited styles, also called BasedOn styles, are a great way to apply multiple styles to a control, because you can’t use more than one style key in the StaticResource reference.

For example, you could reuse a style named MyStyle which sets font size to 12 and add a new Setter element to set the background to Orchid as follows:

<UserControl.Resources>
<Style x:Key="MyStyle" TargetType="Button">
<Setter Property="FontSize" Value="12" />
</Style>
<Style x:Key="InheritedButtonStyle" TargetType="Button"
BasedOn="{StaticResource MyStyle}">
<Setter Property="Background" Value="Red" />
</Style>
</UserControl.Resources>
<StackPanel>
<Button Content="Submit" Width="150" Height="60"  x:Name="btn1"
Style="{StaticResource InheritedButtonStyle}"/>

In this code, InheritedButtonStyle is a style that inherits an earlier style, MyStyle.

Styles versus Control Templates

A style determines the individual properties of a control, whereas a control template determines how the control displays bound data. With a control template, you can assemble several smaller controls into a single control to present varied views of the bound data.

WPF Controls