How to prevent TabControl from doing multi rows?

Unfortunately the TabControl displays a second line for TabItems which do not fit in

the first row. Is there aneasyway to prevent the TabControl from doing multirows, to

enable a TabControl look like VisualStudio or IE7?

[259 byte] By [RolandHasen?hrl] at [2008-1-10]
# 1

I guess it depends on your definition of easy. :)

You would need to modify the ControlTemplate of the TabControl. The default template uses a Grid with a TabPanel in the first row (where the tabs are hosted) and a ContentPresenter in the second row to display the contents of the selected tab.

You could replace the TabPanel with any Panel type you like. Just thinking out loud... you probably want a Grid with three columns. The center column could be a StackPanel with horizontal alignment and then you'd want to put a ScrollViewer around that. That StackPanel would be the ItemsHost for the tabs. In the left and right columns you would want custom Buttons that raise the scroll commands when they are clicked for scrolling left and right.

It may take some XAML work to get it to lay out right, but you need to write zero code to accomplish it. 100% designer type work... and that's the beauty of WPF.

HTH,
Drew

DrewMarsh at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 2

Here. I had some spare time so I whipped together a little sample for ya (see below). Plop that into XAML viewer or something you'll see what I mean. I used EID to reverse engineer the original template, but the important thing to pay attention to is the ScrollViewer and everything in it which replaces the default TabPanel.

HTH,
Drew

<TabControl HorizontalAlignment="Stretch" Margin="104,100,237,83" Width="Auto" x:Name="TabControl" Template="{DynamicResource TabControlControlTemplate1}" IsSynchronizedWithCurrentItem="True" VerticalAlignment="Stretch" Height="Auto">
<TabControl.Resources>
<Style x:Key="TabScrollerRepeatButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="sc#1, 0.366693377, 0.372125238, 0.6931424">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding ContentControl.Content}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

<ControlTemplate x:Key="TabControlControlTemplate1" TargetType="{x:Type TabControl}">
<Grid x:Name="Grid" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="1" Grid.Column="0" x:Name="ContentPanel" BorderBrush="#FFD0CEBF" BorderThickness="0,0,1,1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<Border Background="{TemplateBinding Background}" x:Name="Border1">
<ContentPresenter DataContext="{x:Null}" Margin="{TemplateBinding Padding}" x:Name="PART_SelectedContentHost" Content="{TemplateBinding SelectedContent}" ContentTemplate="{TemplateBinding SelectedContentTemplate}" ContentTemplateSelector="{TemplateBinding SelectedContentTemplateSelector}" ContentSource="SelectedContent"/>
</Border>
</Border>
</Border>
<ScrollViewer x:Name="HeaderPanel" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0,0,0,0" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Disabled">
<ScrollViewer.Style>
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid Margin="0,0,0,0" Grid.Row="0" Grid.Column="0" x:Name="HeaderPanel">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="25"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<RepeatButton Grid.Column="0" Content="&lt;" Command="ScrollBar.LineLeftCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}"/>
<ScrollContentPresenter Grid.Column="1" Content="{TemplateBinding ScrollViewer.Content}" />
<RepeatButton Grid.Column="2" Content="&gt;" Command="ScrollBar.LineRightCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ScrollViewer.Style>
<StackPanel IsItemsHost="true" Orientation="Horizontal" Background="{x:Null}" KeyboardNavigation.TabIndex="1" />
</ScrollViewer>
</Grid>
</TabControl.Resources>
<TabItem x:Name="TabItem" Header="TabItem"/>
<TabItem x:Name="TabItem1" Header="TabItem1"/>
<TabItem x:Name="TabItem2" Header="TabItem2"/>
<TabItem x:Name="TabItem3" Header="TabItem3"/>
<TabItem x:Name="TabItem4" Header="TabItem4"/>
<TabItem x:Name="TabItem5" Header="TabItem5"/>
</TabControl>

DrewMarsh at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 3

Hi Drew
thanks a lot !
in your Sample, a closing </ControlTemplate> is missing (line 60)

</Grid>
</ControlTemplate>
</TabControl.Resources>

WolfgangB at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 4

Hi,

How can u modify this so that the scroller scrolls by one whole tab at a time rather than fractions of a tab width.

Thanks

Paul

xepaul2 at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 5
Cool, this is exactly my definition of easy.
RolandHasen?hrl at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 6

Is it possible to remove the scroll "arrows"?

Thanks in advance,
Marko Vuksanovic

markovuksanovic at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 7
The above code works like a charm. Thank you very much.
Now our users are asking for an enhancement. The repeat buttons should appear only if there is something to scroll. I mean they should appear only if the tab item headers "overflow", not if they still fit into the available space.
Is there any solution for this?

Thanks,
Michael

Muchinger at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...
# 8

Hi,

you can add this to both ToggleButton:

Visibility="{Binding Path=ComputedHorizontalScrollBarVisibility, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"

Also, you need to change the HorizontalScrollBarVisibility to "Auto" for the ScrollViewer.

Patrice

Patbo at 2007-10-3 > top of Msdn Tech,Visual Studio Orcas,Windows Presentation Foundation (WPF)...

Visual Studio Orcas

Site Classified