Quantcast
Channel: .Net Examples
Viewing all articles
Browse latest Browse all 61

WPF - Styles

$
0
0
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 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, we 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 can 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 can do all this in code programmatically as shown below,
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,we can do like this,
this.MyTextBox.Style = (Style)this.MyGrid.FindResource("TextBoxDerivedStyle");


Viewing all articles
Browse latest Browse all 61

Trending Articles