たとえば、WPFを使用してタブコントロールの左上隅に3つのタブ項目を配置し、右上隅に1つのタブ項目を配置する適切な方法は何ですか?
マージンを変更して4番目のタブ項目を右に移動しようとしましたが、これでは良い結果が得られません。まず第一にそれは短くカットされ、第二にそれは選択されたときに正しく表示されません。
問題は、タブをレイアウトするためにTabControlによって内部的に使用されるTabPanelが、必要なものをサポートしていないように見えることです。簡単な回避策は、TabPanelを別のもの(DockPanelなど)に置き換えることです。
<Window x:Class="Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<TabControl>
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border BorderThickness="0,0,1,1" BorderBrush="#D0CEBF" Grid.Row="1">
<Border BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{TemplateBinding BorderBrush}">
<Border Background="{TemplateBinding Background}">
<ContentPresenter ContentSource="SelectedContent"/>
</Border>
</Border>
</Border>
<DockPanel IsItemsHost="True" LastChildFill="False" Margin="2,2,2,0" />
</Grid>
</ControlTemplate>
</TabControl.Template>
<TabItem Header="Item 1" />
<TabItem Header="Item 2" />
<TabItem Header="Item 3" />
<TabItem Header="Item 4" DockPanel.Dock="Right" />
</TabControl>
</Window>
(参照:これは、TabControlのスタイルを設定するためのMSDNの例の修正バージョンです。)
単純なDockPanelは、TabPanelほどスムーズには機能しません。タブを切り替えると、タブが少し「ジャンプ」しますが、これで開始できる場合があります。TabPanelをサブクラス化し、関連する部分をオーバーライドすると、より正確な結果が得られる可能性があります。これにどれだけの努力をしたいかによると思います。
「非表示」のタブを挿入することで、間隔を調整できることがわかりました(つまり、タブを上から下に移動します)。
例えば:
TabItem Height="100" Visibility="Hidden" <br>
TabItem..... <br>
TabItem.... <br>
TabControl内のTabPanelを、目的の動作を提供するカスタムに交換する必要があります。デフォルトのパネルはどれも、箱から出して希望の動作を提供することはありません。
これには、パネル内に含まれるアイテムの数に基づいて必要なカスタム配置を提供するために、MeasureOverrideとArrangeOverrideをオーバーライドする必要がある可能性があります。
これには、TabControlのカスタムControlTemplateが含まれます。デフォルトのTabPanelではなくDockPanelをアイテムホストとして使用する例を試しました。
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle"
Value="True" />
<Setter Property="SnapsToDevicePixels"
Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel Name="HeaderPanel"
LastChildFill="False"
Grid.Row="0"
Panel.ZIndex="1"
Margin="0,0,4,-1"
IsItemsHost="True"
KeyboardNavigation.TabIndex="1"
Background="Transparent" />
<Border Name="Border"
Grid.Row="1"
Background="WhiteSmoke"
BorderBrush="Black"
BorderThickness="1"
CornerRadius="2"
KeyboardNavigation.TabNavigation="Local"
KeyboardNavigation.DirectionalNavigation="Contained"
KeyboardNavigation.TabIndex="2">
<ContentPresenter Name="PART_SelectedContentHost"
Margin="4"
ContentSource="SelectedContent" />
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
問題は、DockPanel.DockプロパティをControlTemplateEGの外部のTabItemsに公開する方法がわからないことです。
<TabControl Margin="10">
<TabItem Header="Tab One" DockPanel.Dock="Left"/>
<TabItem Header="Tab Two" DocKPanel.Dock="Left"/>
<TabItem Header="Tab Three" DocKPanel.Dock="Left"/>
<TabItem Header="Tab Four" DocKPanel.Dock="Right"/>
</TabControl>
// Note: This does not work!!
TabItemをホストするには、独自のPanelを作成する必要があると思います。TabPanelに組み込まれているオーバーフロー動作などを処理する必要があるため、これは非常に多くの作業になることに注意してください。
これを試したとしても、この機能をControlTemplateの外部に公開したい場合は、カスタムTabControlを作成する必要があると思います。
この道を進みたい場合は、この投稿で私の答えを参照してください