WPF の TabControl は
TabItem が増えて横一列に入りきれなくなると多段表示になります。この状態で上段のタブをクリックすると、タブの位置が入れ替わってしまいます。
私はこの動作が大嫌い
タブブラウザみたいにタブの位置はそのままに、内容だけ切り替わってほしい。でも TabControl の標準の動作は前述の通りですし、かといって自分で一から作成するのも面倒。お金を払って商用コントロールを買うなんてもってのほか!
気に入らないなら…
Template を書き変えちゃえばいいのさ!
XAML を記述します
<Window x:Class="TabControlSample.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:classic="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Classic" Title="Window1" Height="300" Width="300"> <Window.Resources> <!--TabControl のタブ位置を固定するスタイル--> <Style TargetType="{x:Type TabControl}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TabControl}"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--TabStrip に WrapPanel を使って位置が変わらないようにする--> <WrapPanel x:Name="HeaderPanel" Margin="0,-2,0,0" Height="Auto" IsItemsHost="True" Grid.Row="0"/> <Grid x:Name="ContentPanel" Grid.Row="1"> <!--HeaderPanel と ContentPanel の境界線を引く--> <classic:ClassicBorderDecorator Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,1,0,0" BorderStyle="Raised"> <!--選択されたタブの内容を表示--> <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent"/> </classic:ClassicBorderDecorator> </Grid> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> <!--タブの幅と高さを固定にする--> <Style TargetType="{x:Type TabItem}"> <Setter Property="Height" Value="28"/> <Setter Property="Width" Value="90"/> </Style> </Window.Resources> <Grid> <TabControl> <TabItem Header="Google"> <Label Content="Google"/> </TabItem> <TabItem Header="Yahoo!"> <Label Content="Yahoo!"/> </TabItem> <TabItem Header="Livedoor"> <Label Content="Livedoor"/> </TabItem> <TabItem Header="Infoseek"> <Label Content="Infoseek"/> </TabItem> <TabItem Header="Microsoft"> <Label Content="Microsoft"/> </TabItem> <TabItem Header="Apple"> <Label Content="Apple"/> </TabItem> </TabControl> </Grid> </Window>
タブ位置固定だけでなく、幅と高さも固定にしてみました。
確認してみます
下段のタブが選択されているところ。
ここで上段の Google タブを選択します。
ページが切り替わったけど、タブの位置は変わっていません。
やった!
まとめ
Template をちょっと書き変えるだけで、タブ位置固定が実現できてしまいました。WPF スゴイ。WinForms ではこうはいきませんね。
TabControl の TabStripPlacement プロパティの値によって、WrapPanel の位置を変更すればもっと良くなりますね。面倒なので今回はしませんが。