Holland
Holland

Reputation: 415

How to center header texts on TabItems

I'm trying to get my WPF TabItems to center their header texts. But no matter which combinations of HorizontalAlignment and HorizontalAlignment (center or stretch) I set on the ContentPresenter and its containing Border, the text always appears aligned to the left, rather than centered. I also don't see a Property on TabItems that I could use to set this directly on the tab items themselves (as it turns out, HorizontalAlignment on a TabItem does something completely different).

My code right now is this:

<Grid TextElement.Foreground="White" TextElement.FontSize="17" TextElement.FontFamily="Times New Roman" HorizontalAlignment="Center" >
   <Border Name="TabBorder" BorderThickness="8 8 8 0"  CornerRadius="12 12 0 0"  
           Background="{StaticResource bandBrush}" HorizontalAlignment="Center" >
   <ContentPresenter HorizontalAlignment="Stretch" ContentSource="Header" Height="24" Width="100" />
   </Border>
 </Grid>

Upvotes: 1

Views: 2469

Answers (2)

NutCracker
NutCracker

Reputation: 12253

I know this question is a bit old and there is already accepted answer but I think my answer could help someone.

My problem was that I needed to spread TabItem headers evenly (each TabItem header has the same width) and text inside header needed to be centered. So this is how I have achieved this:

TabControl.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:FMEA.Resources.Styles"
                xmlns:Converters="clr-namespace:FMEA.Converters"
                xmlns:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro">

<Style x:Key="Custom_TabItem" BasedOn="{StaticResource {x:Type TabItem}}" TargetType="{x:Type TabItem}">
    <Setter Property="Width">
        <Setter.Value>
            <MultiBinding>
                <MultiBinding.Converter>
                    <Converters:TabSizeConverter />
                </MultiBinding.Converter>
                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" />
                <Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type TabControl}}" Path="ActualWidth" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Grid x:Name="tabItem">
                    <Border x:Name="Border">
                        <ContentPresenter x:Name="content"
                                          VerticalAlignment="Center"  
                                          HorizontalAlignment="Center"
                                          ContentSource="Header" />
                    </Border>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter Property="Foreground" Value="Gray" />
                    </Trigger>
                    <Trigger Property="IsSelected" Value="False">
                        <Setter Property="Foreground" Value="LightGray" />
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Foreground" Value="Black" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="HeaderTemplate">
        <Setter.Value>
            <DataTemplate DataType="{x:Type TabItem}">
                <Border x:Name="border">
                    <ContentPresenter>
                        <ContentPresenter.Content>
                            <TextBlock Text="{TemplateBinding Content}"
                                       FontSize="22" HorizontalAlignment="Center" />
                        </ContentPresenter.Content>
                    </ContentPresenter>
                </Border>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

</ResourceDictionary>

where TabSizeConverter is this:

class TabSizeConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        TabControl tabCtrl = values[0] as TabControl;
        double width = tabCtrl.ActualWidth / tabCtrl.Items.Count;
        return width <= 1 ? 0 : width - 1;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Example of usage:

<TabItem Header="MyHeader" Style="{StaticResource Custom_TabItem}">

Upvotes: 1

Noam M
Noam M

Reputation: 3164

You could put the ContentPresenter in a Label with the HorizontalAlignment property set to Strecth and the HorizontalContentAlignment set to Center, Check out this:

<Grid x:Name="gridTabItem">
  <Border x:Name="Border" Margin="0,0,0,0" BorderBrush="{x:Null}" CornerRadius="7,7,0,0" BorderThickness="0" >
    <Label  x:Name="label" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center">
      <ContentPresenter x:Name="ContentSite"
                      VerticalAlignment="Stretch"  
                 HorizontalAlignment="Center"
                 ContentSource="Header" Margin="10,2,10,2"
                 RecognizesAccessKey="True">
      </ContentPresenter>
    </Label>

  </Border>
  <Rectangle x:Name="rectangle" HorizontalAlignment="Left" Height="4" Margin="0,41, 0,0" Stroke="{x:Null}" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" StrokeThickness="0" Fill="{x:Null}"/>
  <Rectangle x:Name="rectangle1" HorizontalAlignment="Left" Height="1" Margin="0,43,0,0" Stroke="{x:Null}" StrokeThickness="0" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" Fill="#FFEEEEEE"/>
  <Rectangle x:Name="glow" HorizontalAlignment="Left" Height="41" Margin="0" Stroke="{x:Null}" StrokeThickness="0" VerticalAlignment="Top" Width="{Binding ActualWidth, ElementName=gridTabItem}" Fill="{x:Null}"/>
</Grid>

Upvotes: 3

Related Questions