Search code examples
wpfmvvmstring-formattingtabitem

WPF TabItem format date


I am trying to create a style for a TabControl to achieve 2 goals:

  1. Display the selected TabItem with a different background color and in bold.
  2. Format the tab header text, bound to a date in the view model, to hours and minutes like "15:45".

I almost succeeded but the header text is also displaying the date part. Besides it is displaying 03:45 instead of 15:45.

see screenshot here

Here is the XAML code I am using:

    <TabControl ItemsSource="{Binding MC}" >
        <TabControl.Resources>
            <Style TargetType="{x:Type TabItem}">
                <Setter Property="Background" Value="#01535F" />
                <Setter Property="Foreground" Value="Azure" />
                <Setter Property="FontSize" Value="16" />
                <Setter Property="BorderBrush" Value="Black" />
                <Setter Property="BorderThickness" Value="1" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TabItem">
                            <Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="Black" Margin="1,1">
                                <Grid Name="Panel">
                                    <ContentPresenter x:Name="ContentSite"
                                    VerticalAlignment="Center"
                                    HorizontalAlignment="Center"
                                    ContentSource="Header"
                                    />
                                    <!--<HeaderedContentControl Header="{Binding Path=MarketStartTime, StringFormat={}{0:HH:mm}}" />-->
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="FontWeight" Value="Bold" />
                                    <Setter TargetName="Panel" Property="Background" Value="#003F44" />
                                </Trigger>
                                <Trigger Property="IsSelected" Value="False">
                                    <Setter TargetName="Panel" Property="Background" Value="#01535F" />
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="FontWeight" Value="Bold" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
                <Setter Property="HeaderTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <HeaderedContentControl Header="{Binding Path=MarketStartTime, StringFormat={}{0:HH:mm}}" />
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TabControl.Resources>
    </TabControl>

Thanks in advance for any help.


Solution

  • I think this is what you're looking for:

    <TabControl ItemsSource="{Binding MC}">
        <TabControl.Resources>
            <Style TargetType="{x:Type TabItem}">
                <Setter Property="Background" Value="#01535F" />
                <Setter Property="Foreground" Value="Azure" />
                <Setter Property="FontSize" Value="16" />
                <Setter Property="BorderBrush" Value="Black" />
                <Setter Property="BorderThickness" Value="1" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="TabItem">
                            <Border Name="Border" BorderThickness="1,1,1,0" BorderBrush="Black" Margin="1,1">
                                <Grid Name="Panel">
                                    <ContentPresenter x:Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Center" ContentSource="Header" />
                                </Grid>
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="True">
                                    <Setter Property="FontWeight" Value="Bold" />
                                    <Setter TargetName="Panel" Property="Background" Value="#003F44" />
                                </Trigger>
                                <Trigger Property="IsSelected" Value="False">
                                    <Setter TargetName="Panel" Property="Background" Value="#01535F" />
                                </Trigger>
                                <Trigger Property="IsMouseOver" Value="true">
                                    <Setter Property="FontWeight" Value="Bold" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TabControl.Resources>
    
        <TabControl.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Path=MarketStartTime, StringFormat={}{0:HH:mm}}"></TextBlock>
            </DataTemplate>
        </TabControl.ItemTemplate>
    </TabControl>
    

    The ItemTemplate is for the header area, the ContentTemplate is for what is showing in the content area. That ContentPresenter in the ContentTemplate will instantiate the controls from the ItemTemplate.