在垂直 TabControl 中对项目进行分组

Grouping items in a vertical TabControl

现状

这是一个样式化的 TabControl 我将其用作程序的侧边栏菜单。右侧的灰色区域是 TabItem 的内容所在的位置。我添加了一些示例文本作为示例。

<ControlTemplate TargetType="{x:Type TabControl}">
    <Grid ClipToBounds="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Local">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Border Background="{StaticResource Accent1_2}" Grid.Column="0" Grid.Row="0" />
        <Border BorderBrush="{StaticResource Accent1_1}" Background="{StaticResource Accent1_3}" Grid.Column="0" Margin="40" Grid.Row="0" BorderThickness="1" VerticalAlignment="Top">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition Height="40" />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <TextBlock Text="{TemplateBinding Tag}" VerticalAlignment="Center" FontSize="18" Margin="5,8,0,8" />
                <StackPanel x:Name="HeaderPanel" Grid.Row="1" Orientation="Vertical" IsItemsHost="True" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1" />
            </Grid>
        </Border>
        <Grid x:Name="ContentPanel" Grid.Column="1" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
            <ContentPresenter x:Name="PART_SelectedContentHost" ContentTemplate="{TemplateBinding SelectedContentTemplate}" Content="{TemplateBinding SelectedContent}" ContentStringFormat="{TemplateBinding SelectedContentStringFormat}" ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
        </Grid>
    </Grid>
</ControlTemplate>

...

<DataTemplate DataType="{x:Type TabItem}">
    <Border x:Name="ContentBorder" Background="White" Height="30">
        <TextBlock x:Name="ContentTextBlock" Margin="5,0,0,0" Foreground="SteelBlue" FontSize="14" Text="{TemplateBinding Content}" VerticalAlignment="Center" />
    </Border>
    <DataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TabItem}}}" Value="True">
            <Setter TargetName="ContentTextBlock" Property="Foreground" Value="{StaticResource Accent1_4}" />
            <Setter TargetName="ContentBorder" Property="Background" Value="{StaticResource Accent1_1}" />
        </DataTrigger>
    </DataTemplate.Triggers>
</DataTemplate>

我的目标

但是,我想将一些项目分组到另一个框中,以便控件看起来像这样:

如何实现 TabControl 的这种外观?

我会完全放弃 TabControl 的想法,只用 ContentPresenter 显示数据

所以你的数据模型会

public ObservableCollection<IItemBase> Items { get; set; }
public ObservableCollection<IItemBase> SpecialItems { get; set; }
public IItemBase SelectedItem { get; set; }

你的 UI 会是这样的

<DockPanel>
    <StackPanel Style="{staticResource NavBarStyle}" DockPanel.Dock="Left">
        <ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
        <ListBox ItemsSource="{Binding SpecialItems}" SelectedItem="{Binding SelectedItem}" />
    </StackPanel>

    <ContentPresenter Content="{Binding SelectedItem}" />
</DockPanel>

您可能需要修改 SelectedItem 的确切实现,以便它正确绑定到两个列表框,但如果这给您带来任何问题,开始工作应该不难。