2010-06-21 68 views
12

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

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

如何将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> 
+0

张贴一些代码来找出哪里出错! – decyclone 2010-06-21 07:11:55

+0

按要求添加代码示例。 – Adrian 2010-06-21 07:38:57

回答

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

谢谢Veer,但是如何在不设置内容的情况下设置tabitem标题字体的颜色?我了解目标名称,但我尝试了几种不喜欢的方式。我不断收到一个错误消息,指出无法在tabitem标题上设置前景。 – Adrian 2010-06-22 00:07:18

+0

@Adrian:为标题内的堆栈面板命名并在目标名称中使用它。 – Amsakanna 2010-06-22 05:44:46

+0

@Veer。对不起,是一个痛苦,但我试过,我无法得到它的工作。也许我做错了(可能!)。你可以发布一些代码给我看?谢谢 – Adrian 2010-06-22 06:16:44

3

这是很老,但我碰到它,而寻找一个类似的问题的答案,我找到了答案,提供根本帮助。 这是我如何解决这个问题。

如果你改变了ContentPresenter给TextBlock在你的TabItem控制模板,像这样:

....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 trigger..ie指定TARGETNAME。

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

当选择该选项卡,而不是绿色的所有其他时间,同时保留单独的应用程序的其余部分的文本颜色这应该给你的绿色文本。

9

我刚刚遇到了这个问题,经过一段时间的摆弄之后,我想我找到了一个更优雅的解决方案。

我说的更优雅,因为它会使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的内容继承(测试)。

享受:)

+2

谢谢吉拉德,这绝对是一个更好的解决方案。让ContentPresenter保持完好无疑是最好的选择。 – thornhill 2011-05-20 21:48:29

+0

我只是把这个例子放在一起。然而'TextElement.Foreground'和'TextElement的设置者。FontWeight'没有效果。如果为网格添加名称'grid',然后添加'',则其背景变为红色。 – 2016-12-15 14:14:14

3

不幸的是,如果你对一些触发一个ContentPresenter设置前景色(或fontWeight设置),你仍然假定头将只包含文本。

如果您设置Header =“SomeHeaderName”(即仅文本),ContentPresenter将生成一个TextBlock来承载此Hertertext; ContentPresenter将成为此TextBlock的(逻辑)父级,因此,ContentPresenter上的新Foreground集将由此TextBlock继承。这工作正常。但是,如果为Header分配了一些可视化树,比如带有Image和TextBlock(甚至是单个TextBlock)的水平StackPanel,那么StackPanel的逻辑父项是TabItem而不是ContentPresenter。继承通过逻辑树工作,所以StackPanel中的TextBlock将最终从TabItem中继承它的Foreground;在ContentPresenter上设置的前景对此没有任何影响。

一个可能的解决方案:DataTemplate最终应用于ContentPresenter,因此DataTemplate的根的TemplatedParent是ContentPresenter;并且继承也通过模板父母 - 儿童障碍起作用。因此,如果您可以设置TabItem.HeaderTemplate而不是TabItem.Header,那么您可以在上设置标题的ContentPresenter上的Foreground,因为HeaderTemplate的根将继承ContentPresenter的Foreground。但是,SelectedContent不会因为前景未在TabItem上设置(并且内容从TabItem继承其Foreground)。

希望这会有所帮助!