Search code examples
wpfxamlcheckboxtabcontroltabitem

How to give a custom shape to a Tab Control in WPF?


enter image description here

I make an application in WPF where I need to use the TabControl to switching between Contents. But due to design purpose my content of the Tab items are in same horizontal line followed by the Tab item header.

Here is the code of my Mainwindow.xaml

<Grid Width="635" HorizontalAlignment="Left" Height="458" VerticalAlignment="Top" Margin="0,61,0,0" >



            <TabControl Margin="-1" BorderThickness="0" Background="#222222" >
               
                <TabItem   Style="{StaticResource TabItemDefaults}"                            Header="File manager"  FontSize="10" Foreground="#efefef" Margin="5,0,0,0" Width="97" Height="20"   FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"                        >

                    <Grid>
                        <Label Name="Folder" Content="Folder:"  FontSize="10" Foreground="#efefef"   Height="20" Width="40"  Margin="-571,-367,0,0"   FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"                                  />
                        <Button Name ="FolderSelect"                               Width="532" HorizontalAlignment="Left" VerticalAlignment="Top"  Height="33" Margin="85,17,0,0"     Background="#1a1a1a"   
                            
                            materialDesign:ShadowAssist.ShadowDepth="Depth0" materialDesign:RippleAssist.Feedback="Transparent" BorderThickness="0"  UseLayoutRounding="True"
                            
                            ></Button>
                        <Label Name="ShowFolders" Content=".." Margin="-479,59,0,0"  Background="#1a1a1a"  Width="168" Height="373"  Foreground="#efefef" ></Label>


                        <Button
    Style="{StaticResource MaterialDesignRaisedButton}"
                           
                            
    Width="65" HorizontalAlignment="Left" Height="25" Background="#FF403D3D" Margin="16,292,0,0" 
                            
                           
    ToolTip="Resource name: MaterialDesignRaisedButton">
                            <materialDesign:PackIcon Kind="PlusThick" />

                        </Button>

                        <Button
    Style="{StaticResource MaterialDesignRaisedButton}"
    Width="65" HorizontalAlignment="Left" Height="25" Background="#FF403D3D" Margin="82,292,0,0" 
    ToolTip="Open output folder">
                            <materialDesign:PackIcon Kind="FolderUpload" />
                        </Button>

                        <Label Content="Video recordings:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="269.2,-22,0,0" Foreground="#efefef"  FontSize="10"  FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display" />
    
                    </Grid>    
                </TabItem>
                <TabItem   Style="{StaticResource TabItemDefaults}"                                           Header ="Preview"   FontSize="10" Foreground="#efefef" Width="67" Height="20" Margin="-8,0,0,0"  FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"                  >

                    <Grid>
                        <CheckBox Content="Draggable mode" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="520,-22,0,0"     Width="110"                                    />


                    </Grid>

                </TabItem>

            </TabControl>


        </Grid>

Both Tab Control and Tab items are made by control template which I declare in App.xaml.

And here is the code of Tab Control which I separately declare in App.xaml -

<Style  TargetType="{x:Type TabControl}"  x:Key="TabControlDefaults"  x:Name="NewTabcontrol" >
                <Setter Property="OverridesDefaultStyle"
          Value="True" />
                <Setter Property="SnapsToDevicePixels"
          Value="True" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TabControl}">
                            <Grid KeyboardNavigation.TabNavigation="Local">
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="Auto" />
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="Disabled">
                                            <Storyboard>
                                                <ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
                                                Storyboard.TargetProperty="(Border.BorderBrush).
                    (SolidColorBrush.Color)">
                                                    <EasingColorKeyFrame KeyTime="0"
                                         Value="#FFAAAAAA" />
                                                </ColorAnimationUsingKeyFrames>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <TabPanel x:Name="HeaderPanel"
                    Grid.Row="0"
                    Panel.ZIndex="1"
                    Margin="0,0,4,-1"
                    IsItemsHost="True"
                    KeyboardNavigation.TabIndex="1"
                    Background="Transparent" />
                                <Border x:Name="Border"
                  Grid.Row="1"
                  BorderThickness="1"
                  CornerRadius="2"
                  KeyboardNavigation.TabNavigation="Local"
                  KeyboardNavigation.DirectionalNavigation="Contained"
                  KeyboardNavigation.TabIndex="2">
                                    <Border.Background>
                                        <LinearGradientBrush EndPoint="0.5,1"
                                   StartPoint="0.5,0">
                                            <GradientStop Color="{DynamicResource ContentAreaColorLight}"
                              Offset="0" />
                                            <GradientStop Color="{DynamicResource ContentAreaColorDark}"
                              Offset="1" />
                                        </LinearGradientBrush>
                                    </Border.Background>
                                    <Border.BorderBrush>
                                        <SolidColorBrush Color="{DynamicResource BorderMediumColor}"/>
                                    </Border.BorderBrush>
                                    <ContentPresenter x:Name="PART_SelectedContentHost"
                              Margin="4"
                              ContentSource="SelectedContent" />
                                </Border>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

And here is the code of Tab Items which I separately declare in App.xaml -

<Style TargetType="{x:Type TabItem}" x:Key="TabItemDefaults" x:Name="NewTabitem"   >

                <Setter Property="Foreground" Value="#bababa" />

                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type TabItem}">
                            <Grid x:Name="Panel"    ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local"                                                      >
                                <ContentPresenter x:Name="ContentSite"
                                        VerticalAlignment="Center"
                                        HorizontalAlignment="Center"
                                        ContentSource="Header"
                                        Margin="10,2"/>
                            
                            
                            </Grid>
                            
                           
                            <ControlTemplate.Triggers>


                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Foreground" Value="Black"/>
                                </Trigger>



                                <Trigger Property="IsSelected" Value="True">
                                    <!--    <Setter TargetName="Panel" Property="Background" Value="LightSkyBlue"  /> -->
                                    <Setter Property="HeaderTemplate">
                                        <Setter.Value>
                                            <DataTemplate>
                                                <TextBlock Text="{TemplateBinding Content}">

                                                    <TextBlock.TextDecorations>
                                                        <TextDecoration  PenOffset="4" PenOffsetUnit="Pixel" >
                                                            <TextDecoration.Pen>
                                                                <Pen Brush="#673ab7" Thickness="4" />
                                                            </TextDecoration.Pen>
                                                        </TextDecoration>
                                                    </TextBlock.TextDecorations>

                                                </TextBlock>
                                            </DataTemplate>
                                        </Setter.Value>
                                    </Setter>


                                </Trigger>
                                <Trigger Property="IsSelected" Value="False">
                                    <Setter TargetName="Panel" Property="Background" Value="#212121" />
                                    <Setter Property="Foreground" Value="WhiteSmoke"/>

                                </Trigger>

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

And my question is the checkbox (I give a red circle) are not functioning properly. I know the main cause is the check box is outside of the tab panel of the Tab Control. But I have to place it there for the design purpose of my Application.

So, how I give a custom shape to the tab panel of the Tab control so that I perfectly dock my content elements where I want.


Solution

  • Your CheckBox can't be selected , you can use DataTrigger to make the chexkbox Visible or Hidden depending on the Preview TabItem selected or not.

    I do some update for your MainWindow.xaml to make the checkbox can be selected.

      <StackPanel Width="635" HorizontalAlignment="Left" Height="458" VerticalAlignment="Top" Margin="0,61,0,0" >
    
        <CheckBox Content="Draggable mode" HorizontalAlignment="Right" VerticalAlignment="Top" Width="110" >
            <CheckBox.Style>
                <Style TargetType="CheckBox">
                    <Setter Property="Visibility" Value="Hidden"></Setter>
                    <Setter Property="IsEnabled" Value="False"></Setter>
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=myTabControl,Path=SelectedItem.Header}" Value="Preview" >
                            <Setter Property="Visibility" Value="Visible"></Setter>
                            <Setter Property="IsEnabled" Value="True"></Setter>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </CheckBox.Style>
        </CheckBox>
    
        <TabControl BorderThickness="0" Background="#222222"  Name="myTabControl" SelectionChanged="myTabControl_SelectionChanged">
    
            <TabItem   Style="{StaticResource TabItemDefaults}" Header="File manager"  FontSize="10" Foreground="#efefef" Margin="5,0,0,0" Width="97" Height="20"   FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"                        >
                <Grid Height="300">
                </Grid>
            </TabItem>
            <TabItem Style="{StaticResource TabItemDefaults}" Header ="Preview"   FontSize="10" Foreground="#efefef" Width="67" Height="20"  FontFamily="Segoe UI" UseLayoutRounding="True" TextOptions.TextFormattingMode="Display"                  >
                <Grid Height="300">
                </Grid>
            </TabItem>
        </TabControl>
    </StackPanel>