0

I wanted to create a TabControl where all TabItems have the same general look but have different Icons inside. All of my styles are in external Resource Dictionary. In Main Window I declared my control like this:

<TabControl Grid.Row="2" TabStripPlacement="Left" >
        <TabItem Style="{StaticResource IconDev}">
            <Label Content="Content 1" />
        </TabItem>
        <TabItem Style="{StaticResource IconTab}">
            <Label Content="Content 2" />
        </TabItem>
    </TabControl

And then I created two styles. First for general look of a Tab Item and then specifically for an icon:

<Style x:Key="IconTab" TargetType="{x:Type TabItem}">
    <Setter Property="MinHeight" Value="70"/>
    <Setter Property="MaxHeight" Value="70"/>
    <Setter Property="MinWidth" Value="70"/>
    <Setter Property="MaxWidth" Value="70"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid>
                    <Border 
                        Name="Border"
                        Margin="0,0,-4,0" 
                        Background="#FFF"
                        BorderBrush="#FFF" 
                        BorderThickness="0" 
                        CornerRadius="0" >
                        <ContentPresenter x:Name="ContentSite"
                              VerticalAlignment="Center"
                              HorizontalAlignment="Center"
                              ContentSource="Header"
                              Margin="0"
                              RecognizesAccessKey="True"/>
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Panel.ZIndex" Value="100" />
                        <Setter TargetName="Border" Property="Background" Value="#000" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter TargetName="Border" Property="Background" Value="#000" />
                        <Setter TargetName="Border" Property="BorderBrush" Value="#000"/>
                        <Setter Property="Foreground" Value="#000"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="IconDev" TargetType="{x:Type TabItem}" BasedOn="{StaticResource IconTab}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <TabItem>
                    <TabItem.Header>
                        <StackPanel>
                            <Viewbox Width="50" Height="50">
                                <Frame Source="icon-dev.xaml" />
                            </Viewbox>
                        </StackPanel>
                    </TabItem.Header>
                </TabItem>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

However something doesn't work well with the inheritance because Style="{StaticResource IconDev}" only inserts the icon but it doesn't apply a general layout declared in Style="{StaticResource IconTab}". What do I do wrong?

ASh
  • 34,632
  • 9
  • 60
  • 82
przemoo83
  • 315
  • 1
  • 3
  • 13
  • `IconDev` should apply Min/Max size setting (inherit from base style). It also reset (override) template of TabItem. so what is wrong? – ASh Apr 08 '16 at 09:11
  • First of all it doesn't apply triggers from `IconTab` it has a default Tab look with icon inside. Secondly it doesn't seem to work. When clicked it won't switch tab. But it does apply size just like you said – przemoo83 Apr 08 '16 at 09:16
  • `IconDev` tempate erased template written in `IconTab` and doesnt have triggers. Size setters are independent from Template setter and they work – ASh Apr 08 '16 at 09:22
  • I'm total noob in wpf and I probably misunderstood the idea of inheritance here. So is it even possible to do something like I planned? – przemoo83 Apr 08 '16 at 09:24

1 Answers1

2

IconDev should apply Min/Max size setting (inherit from base style). It also reset (override, erase) template of TabItem. New template doesn't have triggers. Size setters are independent from Template setter and they work

Tab header content for a single tab can be changed from outside, not in template

E.g. both TabItem use IconTab style, first tab has complex header content

<TabControl TabStripPlacement="Left" >
    <TabItem Style="{StaticResource IconTab}">
        <!--Label is a tab content-->
        <Label Content="Content 1" />

        <TabItem.Header>
            <StackPanel>
                <Viewbox Width="50" Height="50">
                    <Frame Source="icon-dev.xaml" />
                </Viewbox>
            </StackPanel>
        </TabItem.Header>
    </TabItem>

    <TabItem Style="{StaticResource IconTab}" Header="Text">
        <Label Content="Content 2" />
    </TabItem>
</TabControl>

update : derived style can change only header without overriding template

<Style x:Key="IconDev" TargetType="{x:Type TabItem}" BasedOn="{StaticResource IconTab}">
    <Setter Property="Header">
        <Setter.Value>
                <StackPanel>
                    <Viewbox Width="50" Height="50">
                        <Frame Source="icon-dev.xaml" />
                    </Viewbox>
                </StackPanel>
        </Setter.Value>
    </Setter>
</Style>
<TabControl  TabStripPlacement="Left" >
    <TabItem Style="{StaticResource IconDev}">
        <Label Content="Content 1" />                
    </TabItem>
    <TabItem Style="{StaticResource IconTab}" Header="Text">
        <Label Content="Content 2" />
    </TabItem>
</TabControl>
ASh
  • 34,632
  • 9
  • 60
  • 82
  • That was how I first did it but I wanted to make it more elegant and do everything in external style file. Thanks – przemoo83 Apr 08 '16 at 09:39
  • You are a great help I'm finally beginning to understand how this mechanism works – przemoo83 Apr 08 '16 at 10:41
  • @przemoo83, thanks. If at some point you decide that Frame Source must be customized, this question (http://stackoverflow.com/questions/9232502/template-binding-with-attached-properties) and linked Thomas Levesque article might help – ASh Apr 08 '16 at 10:51