i++

プログラム系のメモ書きなど

WPF/XAML : TabControl 中の TabItem の高さを自動で揃える

TabControl に Grid.IsSharedSizeScope="True" を設定し、各 TabItem 内のコンテンツを同じグループの Grid に置くことで高さを共有します。

サンプル

f:id:tkyjhr:20150823070222p:plain

2つめの TabItem の中身の高さを 1つめより低く設定していますが、Grid.IsSharedSizeScope を使うことで 2つめの TabItem を開いてもサイズが縮まらなくなっています。

<Window x:Class="WFPFunctionTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WFPFunctionTest"
        mc:Ignorable="d"
        Title="TabControl" SizeToContent="WidthAndHeight">
    <StackPanel>
        <!-- Grid.IsSharedSizeScope を定義。TabControl 自体が Grid の中にある必要はない -->
        <TabControl Grid.IsSharedSizeScope="True">
            <TabItem Header="Item 1">
                <!-- Grid を定義して SharedSizeGroup に適当な文字列を設定 -->
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition SharedSizeGroup="TabControlGroup"/>
                    </Grid.RowDefinitions>
                    <StackPanel Height="200">
                        <!-- 実際はここにコンテンツを入れる -->
                        <!-- 勿論 StackPanel である必要も Height を指定しておく必要はない -->
                    </StackPanel>
                </Grid>
            </TabItem>
            <TabItem Header="Item 2">
                <!-- 同様に Grid を定義し、SharedSizeGroup に同じ文字列を設定 -->
                <Grid>
                    <Grid.RowDefinitions>
                        <RowDefinition SharedSizeGroup="TabControlGroup"/>
                    </Grid.RowDefinitions>
                    <StackPanel Height="100">
                        <!-- 同上 -->
                    </StackPanel>
                </Grid>
            </TabItem>
        </TabControl>
    </StackPanel>
</Window>

問題点

上のサンプルでは最初に表示される TabItem の高さが最も高いので問題はないのですが、各 TabItem の中身の高さ計算はその Tab を開いたときに行われるので、最初に開いた Tab より大きい Tab を開いた際には Tab の高さが伸びます。

要するに Grid.IsSharedSizeScope="True" を使うと、Tab が縮まることが防げるものの、最初から最大サイズに合わせるということはできないということになります。