WPF Simplified Part 1: Styles

A style in WPF is the collection of (dependency) properties that affect the appearance and behavior of a control. For example, the text color inside a textbox and background of a button.

For our examples, say we’re trying to affect the styles of two textboxes,

<Grid x:Name="MyGrid">
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
                
    <TextBox Grid.Column="0" />
    <TextBox Grid.Column="1" />
</Grid>
 

Since the textboxes don’t have a height and width, lets use a named style to set them.

<Grid.Resources>
    <Style x:Key="TextBoxBaseStyle"> <!—- Named style (because we defined an x:Key) -–>
        <!—- Property=”[ClassName].[DependencyProperty]” -–> 
        <Setter Property="Control.Height" Value="30" />
        <Setter Property="Control.Width" Value="60" />
    </Style>
</Grid.Resources>
 

We’ll need to explicitly apply this style to all the textboxes,

<!—- Both textboxes need to explicitly set the Style properties --> 
<TextBox Grid.Column="0" Style="{StaticResource TextBoxBaseStyle}" />
<TextBox Grid.Column="1" Style="{StaticResource TextBoxBaseStyle}" />
 

Now all the textboxes have the same height and width. We can override a style by declaring the property on the control.

<TextBox Grid.Column="0" Style="{StaticResource TextBoxBaseStyle}" />
<!—- Override the Height property -->
<TextBox Grid.Column="1" Height="60" Style="{StaticResource TextBoxBaseStyle}" />
 

The style we defined (“TextBoxBaseStyle”) can be applied to any type, for example Button,

<Button Grid.Column="2" Style="{StaticResource TextBoxBaseStyle}" />
 

We can do this because the style implicitly targets Control types. If we want to target a particular type, we can use the TargetType property.

<!—- This style will only target TextBox (and TextBox’s derived) types -->
<Style x:Key="TextBoxBaseStyle" TargetType="TextBox">
    <Setter Property="Control.Height" Value="30" />
    <Setter Property="Control.Width" Value="60" />
</Style>
 

If we do this, we’ll no longer be able to apply this style to a Button, but we can apply the style to TextBox derived types. Since the style’s target type is TextBox we can set properties that are specific to a TextBox,

<Style x:Key="TextBoxBaseStyle" TargetType="TextBox">
    <Setter Property="Control.Height" Value="30" />
    <Setter Property="Control.Width" Value="60" />
    <!—- TextBox specific property -–>
    <Setter Property="TextBox.IsReadOnly" Value="True" />
</Style>
 

Also, you could hook into events via an EventSetter.

<Style x:Key="TextBoxBaseStyle" TargetType="TextBox">
    <Setter Property="Control.Height" Value="30" />
    <Setter Property="Control.Width" Value="60" />
    <Setter Property="TextBox.IsReadOnly" Value="True" />
    <!—- Write any custom code in the handler: void OnMouseEnter(object sender, RoutedEventArgs args) -–>
    <EventSetter Event="MouseEnter" Handler="OnMouseEnter" />
</Style>

We could create a typed style and give all the TextBoxes (in the scope of the style) the same properties. This is the whole point of having styles – to define a style once and have multiple controls share it. To create a typed style we need to get rid of the x:Key, 

<Grid.Resources>
    <Style TargetType="TextBox"> <!—- This typed style applies to all textboxes within its scope -–>
                                 <!—- but not TextBox derived types -–> 
        <Setter Property="Control.Height" Value="30" />
        <Setter Property="Control.Width" Value="60" />
        <Setter Property="TextBox.IsReadOnly" Value="True" />
        <EventSetter Event="MouseEnter" Handler="OnMouseEnter" /> 
    </Style>
</Grid.Resources>

<TextBox Grid.Column="0" />
<TextBox Grid.Column="1" Height="60" />
 

But a typed style only applies to the declared type and not derived types (note the difference with a named type).

Styles can also derive from other (named) styles,

<Grid.Resources>
    <Style x:Key="TextBoxBaseStyle">
        <Setter Property="Control.Height" Value="30" />
        <Setter Property="Control.Width" Value="60" />
    </Style>
    <Style x:Key="TextBoxDerivedStyle" TargetType="TextBox" BasedOn="{StaticResource TextBoxBaseStyle}">
        <Setter Property="TextBox.IsReadOnly" Value="True" />
    </Style>
</Grid.Resources>
        
<TextBox Grid.Column="0" Style="{StaticResource TextBoxBaseStyle}"/>
<TextBox Grid.Column="1" Height="60" Style="{StaticResource TextBoxDerivedStyle}"/>
 

And styles can have their own resources,

<Style x:Key="TextBoxDerivedStyle" TargetType="TextBox" BasedOn="{StaticResource TextBoxBaseStyle}">
    <Style.Resources>
        <SolidColorBrush x:Key="TextBoxBackgroundColor" Color="LightGray" />
    </Style.Resources>
    <Setter Property="TextBox.IsReadOnly" Value="True" />
    <Setter Property="TextBox.Background" Value="{StaticResource TextBoxBackgroundColor}" />
</Style>
 

Of course we could do all this in code,

Style textboxStyle = new Style();
textboxStyle.TargetType = typeof(TextBox);

Setter backgroundSetter = new Setter(TextBox.BackgroundProperty, Brushes.LightGray);            
textboxStyle.Setters.Add(backgroundSetter);

this.MyTextBox.Style = textboxStyle;

 

or if the style is already defined in XAML,

this.MyTextBox.Style = (Style)this.MyGrid.FindResource("TextBoxDerivedStyle");
Advertisements

About soumya chattopadhyay
I live and work in Seattle, WA. I work with Microsoft technologies, and I'm especially interested in C#.

5 Responses to WPF Simplified Part 1: Styles

  1. Pingback: WPF Simplified Part 2: Triggers « I.Net

  2. Pingback: WPF Simplified Series « I.Net

  3. Pingback: WPF Simplified Part 6: Control Templates « I.Net

  4. Pingback: WPF Simplified Part 5: Control Templates « I.Net

  5. Pingback: WPF Simplified Part 9: Logical Resources « I.Net

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: