A little while ago, I mentioned about how important I thought it was to create a brand, and I showed you that you can create some interesting looking controls by Templating/Styling the standard System.Windows
controls to create a brand.
I also showed you a ScrollViewer
and a Tab control which I had altered. I have since then decided there is no harm in sharing the TabControl
code that I created.
So in this post, we will discuss what you need to do to change a standard TabControl
from...

...into the following slightly funkier TabControl
.

As one would expect, it's all about the Templates and Styles applied.
The first thing to understand is how the TabControl
is made, it's actually made of a Grid
with 2 rows by default, which is something like this:

So we can alter this, by changing the RowDefinition
to be ColumnDefinition
, which will give us something like:

This is done with the following XAML:
1: <Style x:Key="tab" TargetType="{x:Type TabControl}">
2: <Setter Property="Template">
3: <Setter.Value>
4: <ControlTemplate TargetType="{x:Type TabControl}">
5: <Grid>
6: <Grid.ColumnDefinitions>
7: <ColumnDefinition Width="auto"/>
8: <ColumnDefinition Width="*"/>
9: </Grid.ColumnDefinitions>
10: <StackPanel Orientation="Vertical"
11: Background="{TemplateBinding Background}"
12: Grid.Column="0″
13: Panel.ZIndex="1″
14: IsItemsHost="True"/>
15: <Border
16: Grid.Column="1″
17: BorderBrush="Black"
18: BorderThickness="0″
19: Background="{TemplateBinding Background}"
20: CornerRadius="0″>
21: <ContentPresenter
22: ContentSource="SelectedContent" />
23: </Border>
24: </Grid>
25: </ControlTemplate>
26: </Setter.Value>
27: </Setter>
28: </Style>
So that’s that part. The next thing to understand is the TabItem
. This is easily achieved by a little Style
to replace the standard TabItem
look and feel. This is what creates the individual TabItem
s with the arrows and disabled state.
1: <Style TargetType="{x:Type TabItem}">
2: <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
3: <Setter Property="Template">
4: <Setter.Value>
5: <ControlTemplate TargetType="{x:Type TabItem}">
6: <Grid>
7: <Border
8: Name="Border"
9: Margin="4″
10: BorderBrush="Transparent"
11: BorderThickness="0″
12: CornerRadius="0″ >
13: <StackPanel Orientation="Horizontal">
14:
15: <Polygon x:Name="Arrow"
16: HorizontalAlignment="Left"
17: VerticalAlignment="Center" Margin="4″
18: Width="14″ Height="14″
19: Fill="{TemplateBinding Foreground}"
20: Visibility="Hidden">
21: <Polygon.Points>
22: <Point X="0″ Y="0″ />
23: <Point X="0″ Y="14″ />
24: <Point X="14″ Y="7″ />
25: </Polygon.Points>
26: </Polygon>
27:
28: <!– Header placeholder–>
29: <ContentPresenter x:Name="ContentSite"
30: VerticalAlignment="Center"
31: HorizontalAlignment="Left"
32: ContentSource="Header"
33: Margin="4″
34: RecognizesAccessKey="True"/>
35: </StackPanel>
36: </Border>
37: </Grid>
38: <ControlTemplate.Triggers>
39: <Trigger Property="IsSelected"
40: Value="True">
41: <Setter Property="Panel.ZIndex"
42: Value="100″ />
43: <Setter TargetName="Border"
44: Property="Background"
45: Value="Transparent" />
46: <Setter TargetName="Arrow"
47: Property="Visibility"
48: Value="Visible" />
49: </Trigger>
50: <Trigger Property="IsEnabled"
51: Value="False">
52: <Setter TargetName="Arrow"
53: Property="Fill"
54: Value="{StaticResource Disabled}" />
55: </Trigger>
56: </ControlTemplate.Triggers>
57: </ControlTemplate>
58: </Setter.Value>
59: </Setter>
60: </Style>
And lastly, we need to change the actual TabItem.Header DataTemplate
to respect the disabled state. This is done as follows:
1: <DataTemplate x:Key="tabHeader">
2: <Label x:Name="lbl" Margin="0″ Content="{Binding}"
3: Foreground="{Binding RelativeSource={RelativeSource
4: Mode=FindAncestor, AncestorType={x:Type TabItem},
5: AncestorLevel=1}, Path=Foreground}"
6: VerticalAlignment="Center" />
7: <DataTemplate.Triggers>
8: <Trigger Property="IsEnabled" Value="False">
9: <Setter TargetName="lbl"
10: Property="Foreground"
11: Value="{StaticResource Disabled}" />
12: </Trigger>
13: </DataTemplate.Triggers>
14: </DataTemplate>
So that’s it, all we need to do now is apply these Styles
/Templates
to a TabControl
like so:
1: <TabControl Style="{StaticResource tab}"
2: Background="White" Foreground="Orange">
3: <TabItem Header="Item1 is here"
4: HeaderTemplate="{StaticResource tabHeader}"
5: Foreground="Orange" IsEnabled="False" >
6: <Button Content="Btn1″ Margin="5″/>
7: </TabItem>
8: <TabItem Header="Item2″
9: HeaderTemplate="{StaticResource tabHeader}"
10: Foreground="Orange" >
11: <ScrollViewer >
12: <Canvas x:Name="canv" Width="1200″ Height="1200″>
13: </Canvas>
14: </ScrollViewer>
15: </TabItem>
16: <TabItem Header="Item3″
17: HeaderTemplate="{StaticResource tabHeader}"
18: Foreground="Orange" >
19: <Button Content="Btn3″ Margin="5″/>
20: </TabItem>
21: <TabItem Header="Item4″
22: HeaderTemplate="{StaticResource tabHeader}"
23: Foreground="Orange" >
24: <Button Content="Btn4″ Margin="5″/>
25: </TabItem>
26: </TabControl>
And there you have it.
Here is a small demo project, should you wish to try it yourself.