Raphael Rieber
Raphael Rieber

Reputation: 53

Metro Tab Control Style WPF

I would like to achieve a tabcontrol Style like the one In this project (https://github.com/thielj/MetroFramework). Unfortunately the metroframework project only works for winforms.

Can someone help me to get this styled in xaml?

Would help me alot already, if I have the style for the blue/gray line separating tabitem and tabcontent.

Thanks in advance.

Upvotes: 0

Views: 2915

Answers (1)

Avestura
Avestura

Reputation: 1557

  1. First create two ResourceDictionary to store new templates, one for TabControl and one for TabItem and name them TabControlTemplate.xaml and TabItemTemplate.xaml
  2. Create a copy of default templates for controls mentioned above by right clicking on TabControl and TabItem and then choosing Edit Template > Edit a copy.... Then choose your style names to MetroLikeTabControl and MetroLikeTabItem and set target resource dictionaries for each template. Visual studio creates a copy of that template in selected files.
  3. In TabControlTemplate.xaml add this setter tag to control styles:

    <Setter Property="ItemContainerStyle" Value="{DynamicResource MetroLikeTabItem}" />
    
  4. Then change this part of template:

    <TabPanel Grid.Row="0" Grid.Column="0" x:Name="HeaderPanel" 
              Margin="2,2,2,0" Panel.ZIndex="1"
              Background="Transparent" IsItemsHost="True" KeyboardNavigation.TabIndex="1" />
    

    to this new one:

    <Grid Grid.Row="0" Grid.Column="0">
          <Border BorderThickness="0 0 0 2" BorderBrush="Gray" />
          <TabPanel x:Name="HeaderPanel" Margin="2,2,2,0" Panel.ZIndex="1"
                    Background="Transparent" IsItemsHost="True" KeyboardNavigation.TabIndex="1" />
    </Grid>
    

    this adds a border with only bottom thickness and makes your TabPanel's border overlap with TabItem's border (Why only bottom border? because I'm implementing what you want when TabControl's TabStripPlacement property is set to Top. You can set triggers to implement all other states.

  5. In TabItemTemlate.xaml set a BorderBrush = "0 0 0 2" for element with name innerBorder and remove Opacity = "0" property.

  6. Then change styles of IsMouseOver = true, IsSelected = true and IsSelected = false (default style of a TabItem) as desired. This is my edited trigger for Selected state that changes content of TabItem and color of Border to Blue.

    <MultiDataTrigger>
           <MultiDataTrigger.Conditions>
                          <Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true" />
                          <Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Top" />
           </MultiDataTrigger.Conditions>
           <Setter Property="Panel.ZIndex" Value="1" />
           <!-- commented line below, because we don't need Select Scale behaviour in metro style anymore -->
           <!--<Setter Property="Margin" Value="-2,-2,-2,0" />-->
           <Setter TargetName="innerBorder" Property="Opacity" Value="1" />
           <Setter TargetName="innerBorder" Property="BorderThickness" Value="0,0,0,2" />
           <Setter TargetName="innerBorder" Property="BorderBrush" Value="#0088cc" />
           <Setter TargetName="contentPresenter" Property="TextBlock.Foreground" Value="#0088cc" />
           <Setter TargetName="mainBorder" Property="BorderThickness" Value="0" />
    
    </MultiDataTrigger> 
    

Upvotes: 1

Related Questions