Last Updated 2011/10/13
タブ数が多くてコントロールの幅を超える場合、タブコントロールの標準の動作はタブを複数行で表示します。ここではタブを 1 行表示のままスクロールする手順を説明します
.NET Framework の System.Windows.Forms.TabControl コントロールのほうには Multiline プロパティがあって、タブ数が多い場合、このプロパティに false を設定するとタブは 1 行のままスクロール可能になります。true の場合は複数行で表示されます。
一方、System.Windows.Controls.TabControl コントロールのほうにはそのような機能はありません。そこで、作ってみました。実行結果は以下のとおりです。
リソースディクショナリファイルでタブコントロールのスタイルを再定義します。ポイントは TabPanel コントロールの代わりに ScrollViewer コントロール内に TabItem オブジェクトを配置するようにし、スクロールするための RepeatButton コントロールを配置する点にあります。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Path x:Key="arrowLeft" Stroke="Black" Fill="Black" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center"> <Path.Data> <Geometry>M0,3 L6,6 6,0Z</Geometry> </Path.Data> </Path> <Path x:Key="arrowRight" Stroke="Black" Fill="Black" Stretch="None" VerticalAlignment="Center" HorizontalAlignment="Center"> <Path.Data> <Geometry>M0,0 L6,3 L0,6Z</Geometry> </Path.Data> </Path> <Style x:Key="{x:Type TabControl}" TargetType="TabControl"> <Setter Property="BorderBrush" Value="Black" /> <Setter Property="BorderThickness" Value="1,0,1,1" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TabControl"> <Grid ClipToBounds="True" SnapsToDevicePixels="True" KeyboardNavigation.TabNavigation="Local"> <Grid.RowDefinitions> <RowDefinition Height="24" /> <RowDefinition /> </Grid.RowDefinitions> <DockPanel Grid.Row="0" Height="{TemplateBinding TabPanel.Height}"> <RepeatButton Name="rightButton" Width="24" Height="24" VerticalAlignment="Bottom" Content="{StaticResource arrowRight}" DockPanel.Dock="Right" CommandTarget="{Binding ElementName=scrollViewer}" Command="ScrollBar.LineRightCommand" /> <RepeatButton Name="leftButton" Width="24" Height="24" VerticalAlignment="Bottom" Content="{StaticResource arrowLeft}" DockPanel.Dock="Right" CommandTarget="{Binding ElementName=scrollViewer}" Command="ScrollBar.LineLeftCommand" /> <ScrollViewer Name="scrollViewer" CanContentScroll="True" IsDeferredScrollingEnabled="False" SnapsToDevicePixels="True" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled"> <StackPanel Orientation="Horizontal" IsItemsHost="True" /> </ScrollViewer> </DockPanel> <Border Name="ContentPanel" Grid.Row="1" BorderThickness="{TemplateBinding Border.BorderThickness}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained"> <ContentPresenter ContentSource="SelectedContent" Content="{TemplateBinding TabControl.SelectedContent}" ContentTemplate="{TemplateBinding TabControl.SelectedContentTemplate}" ContentStringFormat="{TemplateBinding TabControl.SelectedContentStringFormat}" Margin="{TemplateBinding Control.Padding}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" /> </Border> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style TargetType="TabItem"> <Setter Property="BorderThickness" Value="1"/> <Setter Property="BorderBrush" Value="Black"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="Margin" Value="0" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TabItem}"> <Border CornerRadius="3,3,0,0" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"> <ContentPresenter ContentSource="Header" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Border> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="True"> <Setter Property="Background" Value="{Binding Background}" /> <Setter Property="BorderThickness" Value="1,1,1,0"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
Window x:Class="TabControlTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="タブ行をスクロール可能にする" Height="300" Width="400"> <!-- ScrollableTabControl.xaml のリソースを読み込む --> <Window.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="ScrollableTabControl.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Window.Resources> <TabControl Margin="10"> <TabItem Header="タブ1"> <TextBlock Text="タブ1を選択しました" /> </TabItem> <TabItem Header="タブ2"> <TextBlock Text="タブ2を選択しました"/> </TabItem> <TabItem Header="タブ3(長いタブ)"> <TextBlock Text="タブ3を選択しました"/> </TabItem> <TabItem Header="タブ4"> <TextBlock Text="タブ4を選択しました"/> </TabItem> <TabItem Header="タブ5(長いタブ)"> <TextBlock Text="タブ5を選択しました"/> </TabItem> <TabItem Header="タブ6"> <TextBlock Text="タブ6を選択しました"/> </TabItem> <TabItem Header="タブ7"> <TextBlock Text="タブ7を選択しました"/> </TabItem> <TabItem Header="タブ8"> <TextBlock Text="タブ8を選択しました"/> </TabItem> </TabControl> </Window>
−以上−