Подтвердить что ты не робот

Хотите сделать прокручиваемые вкладки для tabcontrol

Скажем, у меня есть элемент управления вкладкой, и у меня есть более 50 вкладок, где недостаточно места для хранения так много вкладок, как сделать эти вкладки прокручиваемыми?

4b9b3361

Ответ 1

Отмените 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>

который дает этот результат:

TabControlScroll

Ответ 2

Ответ Рика фактически разрушает вертикальное растяжение содержимого внутри 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>

Ответ 3

Недавно я реализовал такой контроль. Он содержит две кнопки (для прокрутки влево и вправо), которые переключают состояния IsEnabled и Visibility, когда это необходимо. Также он отлично работает с выбором элемента: если вы выберете полувидимый элемент, он будет прокручиваться, чтобы отобразить его полностью.

Это выглядит так:

WPF Scrollable TabControl

Это не так сильно отличается от элемента управления по умолчанию, прокрутка появляется автоматически:

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

Я написал статью об этом ScrollableTabControl классе WpfScrollableTabControl.zip

Ответ 4

Вышеприведенное решение отлично подходит для элементов табуляции, для которых свойство TabStripPlacement управления вкладкой установлено на "Верх". Но если вы хотите иметь свои элементы табуляции, скажите левой стороне, вам нужно будет изменить несколько вещей.

Вот пример того, как заставить scrollviewer работать с 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, чтобы оно по умолчанию было справа.

И вот результат: введите описание изображения здесь

Ответ 5

Поместите его внутри ScrollViewer.

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

</ScrollViewer>

Ответ 6

Для thoose, которые хотят знать, как заставить scrollviewer прокручиваться до выбранной вкладки.

Добавить это событие SelectionChanged = "TabControl_SelectionChanged" в ваш TabControl.

Затем укажите имя, как TabControlScroller, в ScrollViewer внутри шаблона. Вы должны закончить что-то вроде этого

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