WPF - 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,
Since the textBoxes don’t have a height and width, lets use a named style to set them.
We need to explicitly apply this style to all the textBoxes,
Now all the textboxes have the same height and width. We can override a style by declaring the property on the control.
The style we defined (“TextBoxBaseStyle”) can be applied to any type, for example Button,
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.
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,
Also, we could hook into events via an EventSetter.
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,
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,
And styles can have their own resources,
Of course we can do all this in code programmatically as shown below,
OR if the style is already defined in XAML,we can do like this,
<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");
Comments
Post a Comment