简体   繁体   English

如何在滚动的WPF TabControl中更改TabItems的外观?

[英]How to change appearance of TabItems in a scrolling WPF TabControl?

I have a scrolling TabControl, using a ScrollViewer and StackPanel (with the StackPanel set as IsItemsHost="true"). 我有一个滚动的TabControl,使用ScrollViewer和StackPanel(StackPanel设置为IsItemsHost =“true”)。 To begin with, I am working from a solution originally outlined here - Creating Scrolling Tabs Using WPF's TabControl . 首先,我正在使用最初概述的解决方案 - 使用WPF的TabControl创建滚动选项卡 At the moment it has broken links (Edit: I have tracked down one instance of his code in a forum here - How to prevent TabControl from doing multi rows? ), so here is the xaml for the TabControl (does not require any further code): 目前它已断开链接(编辑:我在这里的论坛中跟踪了他的代码的一个实例 - 如何阻止TabControl执行多行? ),所以这里是TabControl的xaml(不需要任何进一步的代码):

<TabControl x:Name="TabControl2" Height="Auto" TabStripPlacement="Bottom" VerticalAlignment="Bottom" Template="{DynamicResource TabControlControlTemplate1}" IsSynchronizedWithCurrentItem="True">
  <TabControl.Resources>
    <Style x:Key="TabScrollerRepeatButtonStyle" TargetType="{x:Type RepeatButton}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate>
            <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1" Margin="1,0">
              <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="{TemplateBinding BorderBrush}" 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="Auto" 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="20"/>
                        <ColumnDefinition Width="20"/>
                        <ColumnDefinition Width="*"/>
                        <ColumnDefinition Width="20"/>
                      </Grid.ColumnDefinitions>
                      <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                      </Grid.RowDefinitions>
                      <RepeatButton Grid.Column="1" Content="&lt;" Command="ScrollBar.LineLeftCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}" Visibility="{Binding Path=ComputedHorizontalScrollBarVisibility, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                      <ScrollContentPresenter Grid.Column="2" Content="{TemplateBinding ScrollViewer.Content}" />
                      <RepeatButton Grid.Column="3" Content="&gt;" Command="ScrollBar.LineRightCommand" Style="{DynamicResource TabScrollerRepeatButtonStyle}" Visibility="{Binding Path=ComputedHorizontalScrollBarVisibility, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}"/>
                    </Grid>
                  </ControlTemplate>
                </Setter.Value>
              </Setter>
            </Style>
          </ScrollViewer.Style>
          <StackPanel IsItemsHost="true" Orientation="Horizontal" Background="{x:Null}" KeyboardNavigation.TabIndex="1"/>
        </ScrollViewer>
      </Grid>
    </ControlTemplate>
  </TabControl.Resources>
  <TabItem x:Name="TabItem1" Header="TabItem1"/>
  <TabItem x:Name="TabItem2" Header="TabItem2"/>
</TabControl>

How might I adjust the appearance of each TabItem? 我如何调整每个TabItem的外观? For instance, I would like to place a TextBox and TextBlock inside each TabItem, with the help of a StackPanel, so that I can have renameable tabs (collapsing one or the other as appropriate). 例如,我想在StackPanel的帮助下在每个TabItem中放置一个TextBox和TextBlock,这样我就可以拥有可重命名的标签(根据需要折叠一个或另一个)。 I might also want to add a close button on each tab. 我可能还想在每个标签上添加一个关闭按钮。 Ordinarily, I would use something like the following: 通常,我会使用以下内容:

                <TabControl.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Name="panel" Orientation="Horizontal">
                            <TextBox   Name="editHeader" Text="{Binding Header}" MaxWidth="250"/>
                            <TextBlock Name="textHeader" Text="{Binding Header}" />
                        </StackPanel>
                    </DataTemplate>
                </TabControl.ItemTemplate>

.. but this is having no effect at all. ..但这根本没有效果。 Any ideas would be appreciated. 任何想法,将不胜感激。 Thanks. 谢谢。

Edit: I am still trying to figure this out. 编辑:我仍然想弄清楚这一点。 Is it possible that the solution could involve ContentPresenter and/or SelectedContentTemplate? 解决方案是否可能涉及ContentPresenter和/或SelectedContentTemplate?

Edit 2: (this doesn't add value to my question) I really, really wish WPF included something of this sort out of the box. 编辑2 :(这不会增加我的问题的价值)我真的,真的希望WPF包含这种开箱即用的东西。 I am baffled by TabControl's default behavior, and by the fact that there is no scrollable TabControl (nor simple solution for attaining one) after some years. 我对TabControl的默认行为感到困惑,并且在几年之后没有可滚动的TabControl(也不是简单的解决方案)。

Hey guesser. 嘿猜猜。 I've done something similar, I based mine off of this series though 我做过类似的事情,但我的基础是这个系列

http://www.blogs.intuidev.com/post/2010/post/2010/01/25/TabControlStyling_PartOne.aspx http://www.blogs.intuidev.com/post/2010/post/2010/01/25/TabControlStyling_PartOne.aspx

The method used is to simply style the tabitems template. 使用的方法是简单地设置tabitems模板的样式。 eg: 例如:

<TabControl.Resources>
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                <!-- your custom template goes here -->

                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</TabControl.Resources>

Unforunately this method means you will have to completely redefine the way the tab items look and behave. 不幸的是,这种方法意味着您必须完全重新定义选项卡项的外观和行为方式。 But the provided link gives good examples on how achieve this. 但是提供的链接提供了如何实现这一目标的良好示例。

Hope it helps. 希望能帮助到你。

Just a thought, 只是一个想法,

have you tried just adding the text block to the TabItem.Header? 你试过将文本块添加到TabItem.Header吗? If you do this instead of a template it might work. 如果你这样做而不是模板,它可能会起作用。 Has for me in the past 对我来说过去了

I think I've got it (though still crossing fingers a bit -- I haven't yet dealt with Visibility of the TextBlock vs TextBox for renaming). 我想我已经得到了它(虽然仍然有点交叉 - 我还没有处理TextBlock与TextBox的Visibility重命名)。

It is similar to Val's solution in that I'm working in TabControl.Resources on its TabItem, but the Property concerned is HeaderTemplate and I just override the ContentPresenter in a DataTemplate. 它类似于Val的解决方案,因为我在其TabItem上使用TabControl.Resources,但相关的属性是HeaderTemplate,我只是覆盖了DataTemplate中的ContentPresenter。 (measures to avoid replacing\\destroying a lot of good behavior that comes for free with the TabControl) (措施避免替换\\破坏TabControl免费提供的许多良好行为)

<TabControl.Resources>
    <Style TargetType="{x:Type TabItem}">
        <Setter Property="HeaderTemplate">
            <Setter.Value>
                <DataTemplate>
                    <ContentPresenter>
                        <ContentPresenter.Content>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{TemplateBinding Content}"/>
                                <TextBox Text="{TemplateBinding Content}"/>
                            </StackPanel>
                        </ContentPresenter.Content>
                    </ContentPresenter>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</TabControl.Resources>

I'm somewhat of a WPF newb, so this is basically a result of persistent experimentation with what I could find Googling. 我有点像WPF新手,所以这基本上是我可以找到谷歌搜索的持续实验的结果。 For those interested, this link (on StackOverflow) helped me most in the end - WPF TabItem Header Styling 对于那些感兴趣的人,这个链接(在StackOverflow上)最终帮助了我 - WPF TabItem Header Styling

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM