Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

On the WPF TabControl - can I add content next to the tab headers?

Tags:

wpf

tabcontrol

Is there an easy way to position another control (i.e. a button) inline and to the right of tab headers in WPF?

In the web, I would use a float or absolute positioning to accomplish this.

The red line in this picture is what I am trying to get to: A control alongside of WPF Tabs
(source: jonkragh.com)

Thanks! Jon

like image 903
Jon Kragh Avatar asked Sep 14 '09 19:09

Jon Kragh


People also ask

How do I hide a tab in WPF?

You can do that by binding the Visibility to the parent control. If you are using a view model, you can bind the visibility to a property in your view model and use the property for both the TabItem and TextBlock. Save this answer.


2 Answers

The robust way to do this is to re-template the TabControl as I did for the close button in my ActiveAwareCommand sample:

<ControlTemplate x:Key="TabControlTemplate" TargetType="TabControl">
    <Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
        <Grid.ColumnDefinitions>
            <ColumnDefinition x:Name="ColumnDefinition0"/>
            <ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition x:Name="RowDefinition0" Height="Auto"/>
            <RowDefinition x:Name="RowDefinition1" Height="*"/>
        </Grid.RowDefinitions>
        <Grid Panel.ZIndex="1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*"/>
                <ColumnDefinition Width="Auto"/>
            </Grid.ColumnDefinitions>
            <TabPanel Margin="2,2,2,0" x:Name="HeaderPanel" IsItemsHost="true" KeyboardNavigation.TabIndex="1"/>
            <Button Grid.Column="1" Command="{Binding DataContext.CloseCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}">X</Button>
        </Grid>
        <Border x:Name="ContentPanel" Grid.Column="0" Grid.Row="1" BorderBrush="#D0CEBF" BorderThickness="0,0,1,1" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
            <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
                <Border Background="{TemplateBinding Background}">
                    <Grid x:Name="PART_ItemsHolder"/>
                </Border>
            </Border>
        </Border>
    </Grid>
</ControlTemplate>

Notice how the TabPanel and Button can never overlap. Result:

alt text

like image 103
Kent Boogaart Avatar answered Nov 16 '22 02:11

Kent Boogaart


Similar to how you would do it on the web, you can just put the tab control and floating control inside a Grid and set the margins of the floating control to get it in the right spot. You could also use a Canvas element to contain the Grid and floating control and set the Canvas.Left and Canvas.Top.

You might need to dynamically measure the width of each tab, if the tabs are not determined at compile time.

like image 42
MKing Avatar answered Nov 16 '22 02:11

MKing