JimDel
JimDel

Reputation: 4359

How can I set a style once for multiple TabItems in WPF?

I'm new to WPF but I would think there is a way that I can set multiple TabItems to use the same Style without adding the Style to each TabItem individually. Like I have done in the first TabItem. Is this possible?

<TabControl Grid.Row="0" x:Name="tabControl" Margin="5,0,5,5" Height="600" Width="998">
   <TabItem x:Name="tabSetToRun" Header="Run" Style="{DynamicResource myTabItemStyle}"/>

   <TabItem x:Name="tabShortcut" Header="Freeze Shortcut"/>
   <TabItem x:Name="tabFullAccess" Header="Full Access"/>
   <TabItem x:Name="tabOldForms" Header="Old Forms"/>
   <TabItem x:Name="tabCFG" Header="CFG Files"/>
</TabControl>

My Style for TabItems is:

     <Style x:Key="myTabItemStyle" TargetType="{x:Type TabItem}">
        <Setter Property="Foreground" Value="White"/>
        <Setter Property="Width" Value="180"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <Grid>
                        <Border 
                            Name="Border"
                            Background="#FF293955"
                            BorderBrush="LightCyan"/>
                        <ContentPresenter x:Name="ContentSite"                                    
                                VerticalAlignment="Stretch"
                                HorizontalAlignment="Stretch"
                                ContentSource="Header"
                                Margin="12,2,12,2"
                                RecognizesAccessKey="True"/>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="FontWeight" Value="Bold"/>
                            <Setter Property="Foreground" Value="Black"/>
                            <Setter Property="Panel.ZIndex" Value="100" />
                            <Setter TargetName="Border" Property="Background" Value="LightCyan" />
                            <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Upvotes: 0

Views: 307

Answers (2)

Kurorion
Kurorion

Reputation: 108

I can't comment on answers yet, but the following will also work. It's based on Szabolcs's answer https://stackoverflow.com/a/34912002/5786449

It's slightly simpler, doesn't require a key on your style and still only apply to this instance of TabItem. But it's less reusable.

<TabControl Grid.Row="0" x:Name="tabControl" Margin="5,0,5,5" Height="600" Width="998">
    <TabControl.Resources>
        <Style x:Key="myTabItemStyle" TargetType="{x:Type TabItem}">
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Width" Value="180"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid>
                            <Border 
                            Name="Border"
                            Background="#FF293955"
                            BorderBrush="LightCyan"/>
                            <ContentPresenter x:Name="ContentSite"                                    
                                VerticalAlignment="Stretch"
                                HorizontalAlignment="Stretch"
                                ContentSource="Header"
                                Margin="12,2,12,2"
                                RecognizesAccessKey="True"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="FontWeight" Value="Bold"/>
                                <Setter Property="Foreground" Value="Black"/>
                                <Setter Property="Panel.ZIndex" Value="100" />
                                <Setter TargetName="Border" Property="Background" Value="LightCyan" />
                                <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </TabControl.Resources>
    <TabItem x:Name="tabSetToRun" Header="Run" />
    <TabItem x:Name="tabShortcut" Header="Freeze Shortcut"/>
    <TabItem x:Name="tabFullAccess" Header="Full Access"/>
    <TabItem x:Name="tabOldForms" Header="Old Forms"/>
    <TabItem x:Name="tabCFG" Header="CFG Files"/>
</TabControl>

Upvotes: 1

Szabolcs D&#233;zsi
Szabolcs D&#233;zsi

Reputation: 8843

Resource lookup happens from the element upward in the visual tree. If a Style doesn't have an x:Key it will be applied to all types of TargetType.

<Window x:Class="TabItemMultiple.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TabItemMultiple"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Width" Value="180"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid>
                            <Border 
                            Name="Border"
                            Background="#FF293955"
                            BorderBrush="LightCyan"/>
                            <ContentPresenter x:Name="ContentSite"                                    
                                VerticalAlignment="Stretch"
                                HorizontalAlignment="Stretch"
                                ContentSource="Header"
                                Margin="12,2,12,2"
                                RecognizesAccessKey="True"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="FontWeight" Value="Bold"/>
                                <Setter Property="Foreground" Value="Black"/>
                                <Setter Property="Panel.ZIndex" Value="100" />
                                <Setter TargetName="Border" Property="Background" Value="LightCyan" />
                                <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid>
        <TabControl Grid.Row="0" x:Name="tabControl" Margin="5,0,5,5" Height="600" Width="998">
            <TabItem x:Name="tabSetToRun" Header="Run" />

            <TabItem x:Name="tabShortcut" Header="Freeze Shortcut"/>
            <TabItem x:Name="tabFullAccess" Header="Full Access"/>
            <TabItem x:Name="tabOldForms" Header="Old Forms"/>
            <TabItem x:Name="tabCFG" Header="CFG Files"/>
        </TabControl>
    </Grid>
</Window>

Remove the x:Key from your Style. If you put the Style in the Resources collection of your Window it changes the TabItems in that Window.

Similarly if you put it in your Application's Resources collection, then they will be changed in the whole application.

You can do this too, if you don't want every TabItem to be changed in the Window:

<Window x:Class="TabItemMultiple.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TabItemMultiple"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="myTabItemStyle" TargetType="{x:Type TabItem}">
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Width" Value="180"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid>
                            <Border 
                            Name="Border"
                            Background="#FF293955"
                            BorderBrush="LightCyan"/>
                            <ContentPresenter x:Name="ContentSite"                                    
                                VerticalAlignment="Stretch"
                                HorizontalAlignment="Stretch"
                                ContentSource="Header"
                                Margin="12,2,12,2"
                                RecognizesAccessKey="True"/>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="FontWeight" Value="Bold"/>
                                <Setter Property="Foreground" Value="Black"/>
                                <Setter Property="Panel.ZIndex" Value="100" />
                                <Setter TargetName="Border" Property="Background" Value="LightCyan" />
                                <Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>

    <Grid>
        <TabControl Grid.Row="0" x:Name="tabControl" Margin="5,0,5,5" Height="600" Width="998">
            <TabControl.Resources>
                <Style TargetType="{x:Type TabItem}" BasedOn="{StaticResource myTabItemStyle}" />
            </TabControl.Resources>
            <TabItem x:Name="tabSetToRun" Header="Run" />

            <TabItem x:Name="tabShortcut" Header="Freeze Shortcut"/>
            <TabItem x:Name="tabFullAccess" Header="Full Access"/>
            <TabItem x:Name="tabOldForms" Header="Old Forms"/>
            <TabItem x:Name="tabCFG" Header="CFG Files"/>
        </TabControl>
    </Grid>
</Window>

Note that the x:Key is now back and we use the BasedOn.

Result

Upvotes: 3

Related Questions