Search code examples
wpftargettype

Why style targettype has to be rebinded back to the original properties?


I am referring to the code block here, on Data triggers

<Window x:Class="WpfTutorialSamples.Styles.StyleDataTriggerSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="StyleDataTriggerSample" Height="200" Width="200">
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <CheckBox Name="cbSample" Content="Hello, world?" />
        <TextBlock HorizontalAlignment="Center" Margin="0,20,0,0" FontSize="48">
            <TextBlock.Style>
                <Style TargetType="TextBlock">
                    <Setter Property="Text" Value="No" />
                    <Setter Property="Foreground" Value="Red" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=cbSample, Path=IsChecked}" Value="True">
                            <Setter Property="Text" Value="Yes!" />
                            <Setter Property="Foreground" Value="Green" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBlock.Style>
        </TextBlock>
    </StackPanel>
</Window>

To me, from programming language design point of view, the line <Style TargetType="TextBlock"> is completely unnecessary, because it is already nested inside the <TextBlock>, so of course whatever setter property should be applied to the TextBlock type. So why need the line <Style TargetType="TextBlock">?

Can <Style TargetType> be of other type except TextBlock?


Solution

  • So why need the line ?

    A Style may be defined as a resource, i.e. not inline, and if doesn't have a TargetType specified, how is the XAML parser supposed to be able to parse it and set the properties specified by the setters? It can't. Or at least it doesn't.

    Just because you can define a Style inline you are still creating an instance of the exact same class that may be used as a (global) resource and then setting a TargetType is indeed required.

    Can be of other type except TextBlock?

    No, apart from a type that is derived from TextBlock. If you specify another type you will get an exception at runtime when the BAML (the compiled XAML) is parsed.