wpf 想要为 tabcontrol 制作可滚动的标签

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5690594/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:48:16  来源:igfitidea点击:

want to make scrollable tabs for a tabcontrol

wpfsilverlight

提问by demaxSH

Say I have a tab control, and I have over 50 tabs, where there is no enough space to hold so many tabs, how make these tabs scrollable?

假设我有一个选项卡控件,我有超过 50 个选项卡,没有足够的空间来容纳这么多选项卡,如何使这些选项卡可滚动?

采纳答案by Rick Sladkey

Override the TabControlControlTemplateand add a ScrollVieweraround the TabPanellike this sample:

重写TabControlControlTemplate并添加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>

which gives this result:

这给出了这个结果:

TabControlScroll

选项卡控件滚动

回答by Kyeotic

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.

Rick 的回答实际上打破了 tabcontrol 内内容的垂直拉伸。可以通过使用两行网格而不是 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>

回答by vortexwolf

Recently I've implemented such control. It contains two buttons (to scroll left and right) which switch their IsEnabledand Visibilitystates 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.

最近我已经实现了这样的控制。它包含两个按钮(向左和向右滚动),可在需要时切换它们的IsEnabledVisibility状态。它也与项目选择完美配合:如果您选择一个半可见的项目,它将滚动以完全显示它。

It looks so:

看起来是这样的:

WPF Scrollable TabControl

WPF Scrollable 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 ScrollableTabControlclass in my blog here.

我已经在我的博客中写了关于这个ScrollableTabControl类的文章。

Source code you can find here: WpfScrollableTabControl.zip

您可以在此处找到源代码:WpfScrollableTabControl.zip

回答by Fütemire

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.

上述解决方案非常适用于选项卡控件的“TabStripPlacement”属性设置为“顶部”的选项卡项。但是,如果您希望拥有选项卡项目,请对左侧说,那么您需要更改一些内容。

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

以下是如何让滚动查看器与左侧的 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>

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.

请注意,在 ScrollViewer 中,我设置了 FlowDirection="RightToLeft" 以便滚动条会捕捉到选项卡项的左侧。如果您将选项卡项放在右侧,则需要删除 FlowDirection 属性,使其默认为右侧。

And here is the result: enter image description here

结果如下: enter image description here

回答by Andrew Shepherd

Place it inside a ScrollViewer.

将它放在ScrollViewer 中

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

</ScrollViewer>

回答by yan yankelevich

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.

将此事件SelectionChanged="TabControl_SelectionChanged" 添加到您的 TabControl。

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

然后为模板内的 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>

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