WPF:限制 TabControl 中 header 区域宽度的最大尺寸

WPF: Limit the maximum size of width of header area in TabControl

我正在使用 C#/WPF 制作 UI。

我的 UI 在选项卡控件的 header 区域有一个按钮,以方便用户使用。

问题是,如果添加了很多选项卡,最后一个(或者如果它有多行,其中一个)可以被那些按钮覆盖,如附图中的红色矩形:

有什么方法可以限制 TabControl header 区域的最大宽度,但保持 TabItems 内容区域的宽度?

当前 XAML:

<Grid>
    <Grid HorizontalAlignment="Stretch">
        <TabControl BorderThickness="0,0,0,1" Margin="0,0,0,0">
             <TabItem MinWidth="130" Height="27" Content="Title" />
             <TabItem MinWidth="130" Height="27" Content="Title" />
             <TabItem MinWidth="130" Height="27" Content="Title" />
             <TabItem MinWidth="130" Height="27" Content="Title" />
             <TabItem MinWidth="130" Height="27" Content="Title" />
             <TabItem MinWidth="130" Height="27" Content="Title" />
             <TabItem MinWidth="130" Height="27" Content="Title" />
             <TabItem MinWidth="130" Height="27" Content="Title" />
        </TabControl>
    </Grid>
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
        <Button Margin="0,2,5,0" HorizontalAlignment="Left" Height="20" Width="22" VerticalAlignment="top" Content="+" />
        <Button Width="65" Height="25" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,0,1,1" Content="Close" />
    </StackPanel>
</Grid>

`

注意:最重要的是,我可以为 TabItems 使用负边距以溢出 parent(TabControl) 的宽度,但这可能是一个糟糕的解决方法。

请告诉我在这种情况下什么是好的方法。

您可以定义自己的 TabControl 样式,或者更具体地说是 ControlTemplate,以像这样插入 "ButtonPanel":

<TabControl.Style>
                    <Style  TargetType="{x:Type TabControl}">
                        <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>
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="*" />
                                            <ColumnDefinition Width="Auto" />
                                        </Grid.ColumnDefinitions>
                                        <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" />
                                        <StackPanel x:Name="ButtonPanel" Grid.Column="1" Orientation="Horizontal">
                                            <Button Margin="0,2,5,0"
                                                    HorizontalAlignment="Left"
                                                    Height="20"
                                                    Width="22"
                                                    VerticalAlignment="top"
                                                    Content="+" />
                                            <Button Width="65"
                                                    Height="25"
                                                    HorizontalAlignment="Right"
                                                    VerticalAlignment="Top"
                                                    Margin="0,0,1,1"
                                                    Content="Close" />
                                        </StackPanel>
                                        <Border x:Name="Border"
                                                Grid.Row="1"
                                                Grid.ColumnSpan="2"
                                                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>
                </TabControl.Style>