在垂直 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
的确切实现,以便它正确绑定到两个列表框,但如果这给您带来任何问题,开始工作应该不难。
现状
这是一个样式化的 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
的确切实现,以便它正确绑定到两个列表框,但如果这给您带来任何问题,开始工作应该不难。