タブコントロールがあり、50を超えるタブがあり、非常に多くのタブを保持するのに十分なスペースがない場合、これらのタブをスクロール可能にするにはどうすればよいですか?
このサンプルのように、TabControl
ControlTemplate
をオーバーライドし、ScrollViewer
の周りにTabPanel
を追加します。
<Grid>
<TabControl>
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<StackPanel>
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Disabled">
<TabPanel x:Name="HeaderPanel"
Panel.ZIndex ="1"
KeyboardNavigation.TabIndex="1"
Grid.Column="0"
Grid.Row="0"
Margin="2,2,2,0"
IsItemsHost="true"/>
</ScrollViewer>
<ContentPresenter x:Name="PART_SelectedContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
ContentSource="SelectedContent"/>
</StackPanel>
</ControlTemplate>
</TabControl.Template>
<TabItem Header="TabItem1">TabItem1 Content</TabItem>
<TabItem Header="TabItem2">TabItem2 Content</TabItem>
<TabItem Header="TabItem3">TabItem3 Content</TabItem>
<TabItem Header="TabItem4">TabItem4 Content</TabItem>
<TabItem Header="TabItem5">TabItem5 Content</TabItem>
<TabItem Header="TabItem6">TabItem6 Content</TabItem>
<TabItem Header="TabItem7">TabItem7 Content</TabItem>
<TabItem Header="TabItem8">TabItem8 Content</TabItem>
<TabItem Header="TabItem9">TabItem9 Content</TabItem>
<TabItem Header="TabItem10">TabItem10 Content</TabItem>
</TabControl>
</Grid>
これにより、次の結果が得られます。
リックの答えは、実際にはタブコントロール内のコンテンツの垂直方向のストレッチを壊します。 StackPanelの代わりに2行のグリッドを使用することで、垂直方向のストレッチを維持するように改善できます。
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden" >
<TabPanel x:Name="HeaderPanel"
Panel.ZIndex ="1"
KeyboardNavigation.TabIndex="1"
Grid.Column="0"
Grid.Row="0"
Margin="2,2,2,0"
IsItemsHost="true"/>
</ScrollViewer>
<ContentPresenter x:Name="PART_SelectedContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
ContentSource="SelectedContent" Grid.Row="1"/>
</Grid>
</ControlTemplate>
</TabControl.Template>
最近、私はそのような制御を実装しました。必要に応じてIsEnabled
とVisibility
の状態を切り替える2つのボタン(左右にスクロールするため)が含まれています。また、アイテムの選択と完全に連携します。半分表示されているアイテムを選択すると、スクロールして完全に表示されます。
それはそう見えます:
デフォルトのコントロールとそれほど違いはなく、スクロールが自動的に表示されます。
<tab:ScrollableTabControl ItemsSource="{Binding Items}"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
IsAddItemEnabled="False"
.../>
このScrollableTabControl
クラスについての記事を書きました 私のブログはこちら 。
ここで見つけることができるソースコード: WpfScrollableTabControl.Zip
上記のソリューションは、タブコントロールの「TabStripPlacement」プロパティが「Top」に設定されているタブアイテムに最適です。ただし、左側などのタブアイテムを探している場合は、いくつか変更する必要があります。
スクロールビューアーを左側のTabStripPlacementで動作させる方法のサンプルを次に示します。
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ScrollViewer
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"
FlowDirection="RightToLeft">
<TabPanel
x:Name="HeaderPanel"
Panel.ZIndex ="0"
KeyboardNavigation.TabIndex="1"
IsItemsHost="true"
/>
</ScrollViewer>
<ContentPresenter
x:Name="PART_SelectedContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
ContentSource="SelectedContent" Grid.Column="1"
/>
</Grid>
</ControlTemplate>
ScrollViewerで、スクロールバーがタブ項目の左側にスナップするようにFlowDirection = "RightToLeft"を設定したことに注意してください。タブアイテムを右側に配置する場合は、FlowDirectionプロパティを削除して、デフォルトで右側になるようにする必要があります。
ScrollViewer 内に配置します。
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Hidden">
<TabControl ...>
...
</TabControl>
</ScrollViewer>
スクロールビューアの作り方を知りたい方へ選択したタブ項目までスクロール。
このイベントSelectionChanged = "TabControl_SelectionChanged"をTabControlに追加します。
次に、テンプレート内のScrollViewerにTabControlScrollerのような名前を付けます。あなたはこのようなもので終わるべきです
<TabControl SelectionChanged="TabControl_SelectionChanged">
<TabControl.Template>
<ControlTemplate TargetType="TabControl">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<ScrollViewer x:Name="TabControlScroller" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" >
<TabPanel x:Name="HeaderPanel"
Panel.ZIndex ="1"
KeyboardNavigation.TabIndex="1"
Grid.Column="0"
Grid.Row="0"
Margin="2,2,2,0"
IsItemsHost="true"/>
</ScrollViewer>
<ContentPresenter x:Name="PART_SelectedContentHost"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
ContentSource="SelectedContent" Grid.Row="1"/>
</Grid>
</ControlTemplate>
</TabControl.Template>
<!-- Your Tabitems-->
</TabControl>
次に、背後のコードでこのメソッドを追加する必要があります:
private void TabControl_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
TabControl tabControl = (TabControl)sender;
ScrollViewer scroller = (ScrollViewer)tabControl.Template.FindName("TabControlScroller", tabControl);
if (scroller != null)
{
double index = (double)(tabControl.SelectedIndex );
double offset = index * (scroller.ScrollableWidth / (double)(tabControl.Items.Count));
scroller.ScrollToHorizontalOffset(offset);
}
}