Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

Custom Tab Style

, 17 Jun 2009 CPOL
Rate this:
Please Sign up or sign in to vote.
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 a

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

image-thumb.png

into the following slightly funkier TabControl

image-thumb1.png

As one would expect its all about the Templates and Styles applied.

The first thing to understand is how the TabControl is made, its actually made of a Grid with 2 rows by default, which is something like this

rows-thumb.jpg

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

cols-thumb.jpg

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&#8243;
  13:              Panel.ZIndex=”1&#8243;
  14:              IsItemsHost=”True”/>
  15:           <Border
  16:              Grid.Column=”1&#8243;
  17:              BorderBrush=”Black”
  18:              BorderThickness=”0&#8243;
  19:              Background=”{TemplateBinding Background}”
  20:              CornerRadius=”0&#8243;>
  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 that the TabItem. This is easily achieved by a little Style to replace the standard TabItem look and feel. This is what creates the individual TabItems 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&#8243;
  10:              BorderBrush=”Transparent”
  11:              BorderThickness=”0&#8243;
  12:              CornerRadius=”0&#8243; >
  13:              <StackPanel Orientation=”Horizontal”>
  14:  
  15:              <Polygon x:Name=”Arrow”
  16:                       HorizontalAlignment=”Left”
  17:                       VerticalAlignment=”Center” Margin=”4&#8243;
  18:                       Width=”14&#8243; Height=”14&#8243;
  19:                       Fill=”{TemplateBinding Foreground}”
  20:                       Visibility=”Hidden”>
  21:                  <Polygon.Points>
  22:                      <Point X=”0&#8243; Y=”0&#8243; />
  23:                      <Point X=”0&#8243; Y=”14&#8243; />
  24:                      <Point X=”14&#8243; Y=”7&#8243; />
  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&#8243;
  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&#8243; />
  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&#8243; 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&#8243; Margin=”5&#8243;/>
   7:      </TabItem>
   8:      <TabItem Header=”Item2&#8243;
   9:               HeaderTemplate=”{StaticResource tabHeader}”
  10:               Foreground=”Orange” >
  11:          <ScrollViewer >
  12:              <Canvas x:Name=”canv” Width=”1200&#8243; Height=”1200&#8243;>
  13:              </Canvas>
  14:          </ScrollViewer>
  15:      </TabItem>
  16:      <TabItem Header=”Item3&#8243;
  17:               HeaderTemplate=”{StaticResource tabHeader}”
  18:               Foreground=”Orange” >
  19:          <Button Content=”Btn3&#8243; Margin=”5&#8243;/>
  20:      </TabItem>
  21:      <TabItem Header=”Item4&#8243;
  22:               HeaderTemplate=”{StaticResource tabHeader}”
  23:               Foreground=”Orange” >
  24:          <Button Content=”Btn4&#8243; Margin=”5&#8243;/>
  25:      </TabItem>
  26:  </TabControl>

And there you have it.

Here is a small demo project, should you wish to try it yourself.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Sacha Barber
Software Developer (Senior)
United Kingdom United Kingdom
I currently hold the following qualifications (amongst others, I also studied Music Technology and Electronics, for my sins)
 
- MSc (Passed with distinctions), in Information Technology for E-Commerce
- BSc Hons (1st class) in Computer Science & Artificial Intelligence
 
Both of these at Sussex University UK.
 
Award(s)

I am lucky enough to have won a few awards for Zany Crazy code articles over the years

  • Microsoft C# MVP 2014
  • Codeproject MVP 2014
  • Microsoft C# MVP 2013
  • Codeproject MVP 2013
  • Microsoft C# MVP 2012
  • Codeproject MVP 2012
  • Microsoft C# MVP 2011
  • Codeproject MVP 2011
  • Microsoft C# MVP 2010
  • Codeproject MVP 2010
  • Microsoft C# MVP 2009
  • Codeproject MVP 2009
  • Microsoft C# MVP 2008
  • Codeproject MVP 2008
  • And numerous codeproject awards which you can see over at my blog

Comments and Discussions

 
GeneralUse as traditional control PinmemberVin5518-Aug-09 11:58 
GeneralRe: Use as traditional control PinmvpSacha Barber18-Aug-09 21:59 
GeneralRe: Use as traditional control PinmemberVin5518-Aug-09 23:44 
GeneralRe: Use as traditional control PinmvpSacha Barber19-Aug-09 0:05 
GeneralRe: Use as traditional control PinmemberVin5519-Aug-09 0:11 
GeneralRe: Use as traditional control PinmvpSacha Barber19-Aug-09 0:30 
GeneralRe: Use as traditional control PinmemberVin5519-Aug-09 1:47 
GeneralRe: Use as traditional control PinmvpSacha Barber19-Aug-09 5:29 
GeneralRe: Use as traditional control PinmemberVin5519-Aug-09 7:46 
GeneralStating the Obvious Pinmembersam.hill17-Jun-09 6:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411022.1 | Last Updated 17 Jun 2009
Article Copyright 2009 by Sacha Barber
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid