ccaron
ccaron

Reputation: 71

Global TextBlock style messing with named Label style

I created a very simple WPF application with the following resources:

<Application x:Class="StyleTest.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
<Application.Resources>
    <FontFamily x:Key="MainFontFamily">Calibri</FontFamily>

    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="FontFamily" Value="{StaticResource MainFontFamily}" />
    </Style>

    <Style x:Key="HyperlinkLabel" TargetType="{x:Type Label}">
        <Setter Property="Cursor" Value="Hand" />
        <Setter Property="Foreground" Value="Yellow" />
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Foreground" Value="Red"/>
            </Trigger>
        </Style.Triggers>
    </Style>

</Application.Resources>

The TextBlock style doesn't have a x:Key property. I want this property to apply to all the TextBlocks.

The UI is simply:

<Window x:Class="StyleTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="Test 123 Test 123" Style="{StaticResource HyperlinkLabel}" />

    </Grid>
</Window>

When I run the application:

  1. "Test 123 Test 123" is displayed in yellow.
  2. When I put the mouse cursor over the text, the mouse cursor icon changes to a hand with a pointing finger.
  3. When I put the mouse cursor over the text, the text turns red.

Great. But if I changed the first style from:

    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="FontFamily" Value="{StaticResource MainFontFamily}" />
    </Style>

to

    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="FontFamily" Value="{StaticResource MainFontFamily}" />
        <Setter Property="Foreground" Value="Blue" />
    </Style>

Then, when running the application:

  1. The text is displayed in blue instead of yellow. This is bad.
  2. When I put the mouse cursor over the text, the mouse cursor icon changes to a hand with a pointing finger. This is ok.
  3. When I put the mouse cursor over the text, the text stays blue. This is bad.

Why is the TextBlock style messing up with the Label style? I seems that Label inherits from TextBlock. But even if it is the case, the Label style should be used no?

How can I “force” the use of the Label style? How can the Label style overwritte the TextBlock style?

Thanks!

Upvotes: 0

Views: 482

Answers (1)

Rachel
Rachel

Reputation: 132558

Implicit styles in Application.Resources applied to non-control items such as TextBlock do not respect control boundaries, and will apply to the entire application regardless of what other definitions exist. This was probably done to allow for global application-wide styling, such as font, text sizes, colors, etc.

Two solutions to fix this :

  1. Change implicit style to a Label, which inherits from Control. Because it is a Control, it will respect control boundaries and not try to overwrite the properties of every text element in your application.

  2. Move the style to Window.Resources instead of Application.Resources. This way the style isn't considered global for the entire application, so isn't treated as such when deciding how to render items.

I had the same question a while back, and this is the best I could make of the description given. Implicit styles in Application.Resources vs Window.Resources? :)

Upvotes: 1

Related Questions