设置TabItem前景色也设置TabControl前景色

时间:2010-06-21 02:09:39

标签: wpf styling tabitem

我有一个TabControl,我已经重新设计了。 TabItem有一个触发器,当选择TabItem时会触发该触发器,将TabItem文本更改为粗体和绿色。我遇到的问题是选项卡内容中的文本也设置为粗体和绿色。

我可以通过将选项卡内容中的所有控件设置为我想要的颜色和字体重量来解决这个问题,但是我应该这样做吗?所以,我必须确保内容区域中的每个文本块都有一个样式,将颜色设置为黑色,字体权重正常。

如何设置TabItem的IsSelected部分显示绿色,但仅保留选项卡的内容?

我试图将TabControl的前景设置为黑色,但这不起作用。

您将从下面的代码示例中看到第一个选项卡上的文本为绿色,我希望它为黑色,但不在选项卡内容中设置每个控件。

以下代码示例:

    <Grid>
    <Grid.Resources>
        <!-- Tab item -->
        <Style TargetType="{x:Type TabItem}">
            <Setter Property="FontSize" Value="14"/>
            <Setter Property="MinWidth" Value="200"/>
            <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Grid>
                            <Border Name="Border" Padding="5,2">
                                <ContentPresenter ContentSource="Header"/>
                            </Border>
                        </Grid>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Border.IsMouseOver" Value="True"/>
                                    <Condition Property="IsSelected" Value="False"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="FontWeight" Value="Bold"/>
                                <Setter Property="Foreground" Value="Black"/>
                            </MultiTrigger>

                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Border.IsMouseOver" Value="False"/>
                                    <Condition Property="IsSelected" Value="False"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Foreground" Value="Black" />
                            </MultiTrigger>

                            <Trigger Property="IsSelected" Value="True">
                                <Setter Property="Foreground" Value="Green"/>
                                <Setter Property="FontWeight" Value="Bold"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <!-- Tab control -->
        <Style  TargetType="{x:Type TabControl}">
            <Setter Property="SelectedIndex" Value="0"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="200" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Border Grid.Column="0" Padding="5" Margin="0,0,5,0" CornerRadius="3">
                                <StackPanel Orientation="Vertical">
                                    <ScrollViewer VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}">
                                        <TabPanel IsItemsHost="True"/>
                                    </ScrollViewer>
                                </StackPanel>
                            </Border>
                            <Border Grid.Column="1" BorderBrush="Black" BorderThickness="0">
                                <ScrollViewer VerticalScrollBarVisibility="Auto" FocusVisualStyle="{x:Null}" Padding="10,0">
                                    <ContentPresenter ContentSource="SelectedContent"/>
                                </ScrollViewer>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Grid.Resources>

    <TabControl Name="tabControl" TabStripPlacement="Left">
        <!-- First tab item -->
        <TabItem IsSelected="True">
            <TabItem.Header>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Profile"/>
                </StackPanel>
            </TabItem.Header>
            <TextBlock Text="Page 1 Sample Text with no foreground set." FontSize="30"/>
        </TabItem>

        <!-- Second tab item -->
        <TabItem IsSelected="True">
            <TabItem.Header>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Profile"/>
                </StackPanel>
            </TabItem.Header>
            <TextBlock Text="Page 2 Sample Text with foreground set manually." FontSize="30" Foreground="Red"/>
        </TabItem>
    </TabControl>
</Grid>

4 个答案:

答案 0 :(得分:11)

我刚刚遇到过同样的问题,稍微调整一下之后我觉得我找到了一个更优雅的解决方案。

我说的更优雅,因为它会使ContentPresenter保持原样,并将前景和字体量设置器应用于ContentPresenter的TextElement(它基本上是一个附加属性,但这不是重点)。

这种方法的主要优点是用TextBlock替换ContentPresenter隐含地假定标题只包含文本,这限制了变通方法的可用性并产生了不太健壮的代码。保留ContentPresenter将允许任何内容,例如图像+文本。

您需要做的另一件事是命名您的ContentPresenter:

<Setter Property="Template">
     <Setter.Value>
         <ControlTemplate TargetType="{x:Type TabItem}">
             <Grid>
                <Border Name="Border" Padding="5,2">
                   <ContentPresenter x:Name="CP" ContentSource="Header"/>
                </Border>
             </Grid>
             <ControlTemplate.Triggers>
                <MultiTrigger>
                   <MultiTrigger.Conditions>
                      <Condition Property="Border.IsMouseOver" Value="True"/>
                      <Condition Property="IsSelected" Value="False"/>
                   </MultiTrigger.Conditions>
                     <Setter Property="TextElement.FontWeight" TargetName="CP" Value="Bold"/>
                     <Setter Property="TextElement.Foreground" TargetName="CP" Value="Black"/>                                
                </MultiTrigger>...

现在,前景和FontWeight不会被TabItem(已测试)的内容继承。

享受:)

答案 1 :(得分:3)

这是相当古老的,但我在寻找类似问题的答案时遇到了它,我发现提供的答案根本没有帮助。 以下是我修复此问题的方法。

如果您将ContentPresenter更改为tabitem的控件模板中的TextBlock,请执行以下操作:

....stuff above here...
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
   <Border Name="Border" Padding="5,2">
        <TextBlock x:Name="TabItemContent" Text="{TemplateBinding Header}"/>
   </Border>
</Grid>
... stuff below here....

然后在该控制模板的触发器中,在IsSelected触发器中指定目标名称。

...stuff above here...
 <Trigger Property="IsSelected" Value="True">
     <Setter Property="Foreground" TargetName="TabItemContent" Value="Green"/>
     <Setter Property="FontWeight" Value="Bold"/>
</Trigger>
... stuff below here ...

选择选项卡时,应该为您提供绿色文本,而在其他时间不提供绿色,同时仅在应用程序的其余部分留下文本着色。

答案 2 :(得分:3)

不幸的是,如果你通过某个触发器在ContentPresenter上设置Foreground(或FontWeight),你仍然认为标题只包含Text。

如果设置Header =“SomeHeaderName”(即仅文本),ContentPresenter将生成一个TextBlock来托管此headertext; ContentPresenter将是此TextBlock的(逻辑)父级,因此,ContentPresenter上的新Foreground将由此TextBlock继承。这没问题。

但是,如果为Header分配了一些可视化树,例如带有Image和TextBlock(甚至单个TextBlock)的水平StackPanel,则StackPanel的逻辑父级是TabItem而不是ContentPresenter。继承通过逻辑树工作,因此StackPanel内的TextBlock最终将再次从TabItem继承其Foreground;在ContentPresenter上设置的前景对此没有任何影响。

一种可能的解决方案:DataTemplate最终应用于ContentPresenter,因此DataTemplate根的TemplatedParent是ContentPresenter;和继承也通过TemplatedParent-Child屏障工作。因此,如果您能够设置TabItem.HeaderTemplate而不是TabItem.Header,那么可以在标题的ContentPresenter上设置Foreground,因为HeaderTemplate的根将从ContentPresenter继承Foreground。但是,SelectedContent不会因为未在TabItem上设置Foreground(并且内容从TabItem继承其Foreground)。

希望这有帮助!

答案 3 :(得分:0)

wpf中的每个控件都从其父级继承属性。由于TabItem的颜色为黑色,因此其子textblock也是黑色。现在,因为您已将整个TabItem的前景颜色更改为绿色,所以它的所有子项都将继承它。

在这里,您可以将TabItem.Header或其内容的前景设置为绿色,这样它就不会影响TabItem中的其他内容。否则你可以反转解决方案。

否则试试这个:

<Window.Resources>
    <DataTemplate x:Key="greenHeaderTemplate">
        <StackPanel Orientation="Horizontal"> 
            <TextBlock Text="Profile" 
                       FontWeight="Bold" 
                       Foreground="Green"/> 
        </StackPanel> 
    </DataTemplate>
    <DataTemplate x:Key="defaultHeaderTemplate">
        <StackPanel Orientation="Horizontal"> 
            <TextBlock Text="Profile"/> 
        </StackPanel> 
    </DataTemplate>
</Window.Resources>

<Trigger Property="IsSelected" Value="True">      
    <Setter Property="HeaderTemplate" 
            Value="{StaticResource greenHeaderTemplate}"/> 
</Trigger>

<TabItem IsSelected="True" HeaderTemplate="{StaticResource defaultHeaderTemplate}"> 
    <TextBlock Text="Page 1 Sample Text with no foreground set." FontSize="30"/> 
</TabItem>