2010-06-21 81 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)。

希望這會有所幫助!