开发者

want to make scrollable tabs for a tabcontrol

开发者 https://www.devze.com 2023-02-25 03:17 出处:网络
Say I have a tab control, and I have over 50 tabs, where there is no enoug开发者_开发问答h space to hold so many tabs, how make these tabs scrollable?Rick\'s answer actually breaks the vertical stretc

Say I have a tab control, and I have over 50 tabs, where there is no enoug开发者_开发问答h space to hold so many tabs, how make these tabs scrollable?


Rick's answer actually breaks the vertical stretching of content inside the tabcontrol. It can be improved to retain vertical stretching by using a two row grid instead of a StackPanel.

<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>


Override the TabControl ControlTemplate and add a ScrollViewer around the TabPanel like this sample:

<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>

which gives this result:

want to make scrollable tabs for a tabcontrol


Recently I've implemented such control. It contains two buttons (to scroll left and right) which switch their IsEnabled and Visibility states when it is necessary. Also it works perfectly with item selection: if you select a half-visible item, it will scroll to display it fully.

It looks so:

want to make scrollable tabs for a tabcontrol

It isn't so much different from the default control, the scrolling is appeared automatically:

<tab:ScrollableTabControl ItemsSource="{Binding Items}" 
    SelectedItem="{Binding SelectedItem, Mode=TwoWay}" 
    IsAddItemEnabled="False" 
    .../>

I've written the article about this ScrollableTabControl class in my blog here.

Source code you can find here: WpfScrollableTabControl.zip


The above solution is great for tab items with the tab control's "TabStripPlacement" property set to "Top". But if you are looking to have your tab items, say to the left side, then you will need to change a few things.

Here is a sample of how to get the scrollviewer to work with the TabStripPlacement to the Left:

<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>

Note that in the ScrollViewer I set FlowDirection="RightToLeft" so that the scroll bar would snap to the left of the tab items. If you are placing your tab items to the right the you will need to remove the FlowDirection property so that it defaults to the right side.

And here is the result:

want to make scrollable tabs for a tabcontrol


For thoose who want to know how to make the scrollviewer scroll to the selected tab item.

Add this event SelectionChanged="TabControl_SelectionChanged" to your TabControl.

Then give a name like TabControlScroller to the ScrollViewer inside the template. You should end with something like this

<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>

Then in code behind you just have to add this method :

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);
    }
}


Place it inside a ScrollViewer.

<ScrollViewer  HorizontalScrollBarVisibility="Auto"  VerticalScrollBarVisibility="Hidden">
    <TabControl ...>
         ...
    </TabControl>

</ScrollViewer>
0

精彩评论

暂无评论...
验证码 换一张
取 消