Multiline TabItem Header in WPF

axnst2
axnst2 used Ask the Experts™
on
Hi Experts,

          I have a Style defined for my TabItems for a Tab Control under WPF.  How do I need to change my below code to accomplish having multiline TabItem Header's like in the picture:

Tabs
Here's my code.  I have everything I want except the multiline header text:

<Style TargetType="{x:Type TabItem}">
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid Width="200" Height="70">
                            <Border Name="Border" Background="Black" BorderBrush="White" BorderThickness="1,1,1,1" CornerRadius="6,6,0,0" >
                                <TextBlock TextWrapping="Wrap"  Height="70" Width="200" VerticalAlignment="Center" TextAlignment="Center" HorizontalAlignment="Stretch" >
                                    <ContentPresenter x:Name="ContentSite" ContentSource="Header" Margin="2,0,0,0"/>
                                </TextBlock>                                
                            </Border>                            
                        </Grid>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsSelected" Value="True">
                                <Setter TargetName="Border" Property="Background" Value="#009900" />
                            </Trigger>
                            <Trigger Property="IsSelected" Value="False">
                                <Setter TargetName="Border" Property="Background" Value="Black" />
                            </Trigger>
                        </ControlTemplate.Triggers>

                    </ControlTemplate>
                </Setter.Value>
            </Setter>            
        </Style>

Open in new window



Thanks!
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Aaron JabamaniTechnical Architect
Commented:

Simpler way would be have two textboxes..

<TabControl>
       <TabItem>
         <TabItem.Header>
           <StackPanel Orientation="Horizontal">
             <TextBlock Text="{Bindinging FirstLine}" Margin="2,0,0,0" VerticalAlignment="Center" />
              <TextBlock Text="{Bindinging SecondLine}" Margin="2,0,0,0" VerticalAlignment="Center" />
           </StackPanel>
         </TabItem.Header>
       </TabItem>
 </TabControl>

not sure of this give a try. Have only one text in above and set a fixed width and height for the textbox. Enable Textwrapping=true that should split the lines if there are any spaces btw the words.
I think that the problem possibly originates in the amount of space the textblock is thought to have when WPF performs the layout.

Applying a DataTemplate to the Header seems to be a way that gets WPF to look at the specfied width.

The appended codes defines a TabControl that wraps the header text and reacts to the IsSelected property of the TabItem.
It's set with a MaxWidth on the header's border to allow it to shrink to fit, you can change that to a fixed Width if you want.
It won't wrap unless the text is longer than the spcified width, so your original 200x70 seems a little large.

Hope this helps
<TabControl >
            <TabControl.Resources>
                <Style TargetType="Border">
                    <Setter Property="Background" Value="Black"/>
                </Style>
                <DataTemplate x:Key="TabHeaderTemplate">
                    <Border Name="TabBorder" MaxWidth="60" BorderBrush="White" BorderThickness="1,1,1,1" CornerRadius="6,6,0,0" Padding="4,0">
                        <Border.Style>
                            <Style TargetType="Border">
                                <Setter Property="Background" Value="Black"/>
                            </Style>
                            </Border.Style>
                        <TextBlock Text="{Binding}" Foreground="White" TextAlignment="Center"  Height="40"  TextWrapping="Wrap"/>
                    </Border>
                    <DataTemplate.Triggers>
                        <DataTrigger 
                            Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}, Path=IsSelected}" Value="True">
                            <Setter   TargetName="TabBorder" Property="Background" Value="#009900" />
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
                <Style TargetType="TabItem">
                    <Setter Property="HeaderTemplate" Value="{StaticResource TabHeaderTemplate}"/>
                </Style>
            </TabControl.Resources>
            <TabItem  Header="Mike's Tab" IsSelected="True"/>
            <TabItem Header="Another One" />
            <TabItem Header="Short" />
        </TabControl>

Open in new window

axnst2IT Manager
Commented:
Neither answers were the solutions.  I ended up just putting two TextBoxes in and I split the string behind the seen at run time.  A work-around at best...
Vaughn BighamSr. Software Engineer / Architect

Commented:
If you are specifying the headers in xaml, you could try using a textblock with a line break.  

 
<TextBlock>FirstLine <LineBreak />Second Line</TextBlock>

Open in new window

axnst2IT Manager

Author

Commented:
For the effort- I don't know all the answers either...

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial