Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why a Listbox DataTemplate does not use the Windows.Resources styles?

I have the following XAML (simplified):

<Window ...

    <Window.Resources>
        <Style TargetType="{x:Type TextBlock}" >
            <Setter Property="FontSize" Value="28" />
            <Setter Property="Margin" Value="3" />
            <Setter Property="Foreground" Value="Green" />
        </Style>
    </Window.Resources>

    <StackPanel>

        <ListBox ItemsSource=...
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal" >
                        <TextBlock Text="{Binding Index}" />
                        <TextBlock Text="-" />
                        <TextBlock Text="{Binding Hours, StringFormat={}{0:00}}" />
                        <TextBlock Text=":" />
                        <TextBlock Text="{Binding Minutes, StringFormat={}{0:00}}" />
                        <TextBlock Text=":" />
                        <TextBlock Text="{Binding Seconds, StringFormat={}{0:00}}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

        ...

With this code the Style defined in the Window.Resources is not being applied to the TextBlock inside the DataTemplate but it is on other TextBlocks on the Window.

If I copy the Style and set it in the DataTemplate resources like this:

        <DataTemplate.Resources>
            <Style TargetType="{x:Type TextBlock}" >
                <Setter Property="FontSize" Value="28" />
                <Setter Property="Margin" Value="3" />
                <Setter Property="Foreground" Value="Green" />
            </Style>
        </DataTemplate.Resources>

Then it works. Any idea why do I need to duplicate the style?

Thanks in advance.

like image 874
Ignacio Soler Garcia Avatar asked Jan 13 '23 05:01

Ignacio Soler Garcia


2 Answers

Implicit Styles will apply in templates only to types that inherit from System.Windows.Controls.Control and since TextBlock inherits directly from System.Windows.FrameworkElement it won't work. You have to either give your style x:Key and use it explicitly or declare your style in Application.Resources but then it will apply to all TextBlocks and by this I mean basically every displayed bit of text, in whole application

like image 191
dkozl Avatar answered Jan 14 '23 18:01

dkozl


It's a WPF quirk. When a control doesn't inherit from Control, but directly from FrameworkElement, implicit style lookup inside a template skips directly to the application resources. If you put the style in the application resources (App.xaml) it would work.

Alternatively, you can use a named resource and BasedOn to reference it:

    <DataTemplate.Resources>
        <Style TargetType="TextBlock" BasedOn="{StaticResource MyTextStyle}" />
    </DataTemplate.Resources>
like image 44
Eli Arbel Avatar answered Jan 14 '23 18:01

Eli Arbel