2010-06-21 4 views
12

J'ai un TabControl que je redécoré. Le TabItem a un déclencheur qui est déclenché lorsque le TabItem est sélectionné qui modifie le texte TabItem en gras et vert. Le problème que j'ai est que le texte dans le contenu de l'onglet est également mis en gras et vert.Réglage TabItem couleur de premier plan définit également la couleur de premier plan TabControl

Je peux travailler autour de cela en définissant tous mes contrôles dans le contenu de tabulation pour être le poids de la couleur et la police que je veux, mais dois-je faire cela? Donc, je dois vous assurer que tous les textblock dans la zone de contenu a un style qui définit la couleur noir poids et la police normale.

Comment puis-je régler la partie IsSelected du TabItem pour montrer vert, mais laisser le contenu de l'onglet seul?

J'ai essayé de mettre au premier plan du TabControl au noir, mais cela ne fonctionne pas.

Vous verrez à partir de l'exemple de code ci-dessous que le texte sur le premier onglet est vert, et je veux qu'il soit noir, mais sans définir chaque contrôle dans le contenu de l'onglet.

code

Exemple ci-dessous:

<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

Postez un code pour savoir ce qui ne va pas! – decyclone

+0

Échantillon de code ajouté comme demandé. – Adrian

Répondre

0

Chaque contrôle WPF hérite des propriétés de son parent. Étant donné que la couleur du TabItem était noir, son enfant textblock était également de couleur noire. Maintenant que vous avez changé la couleur de premier plan de TabItem en vert, tous ses enfants l'hériteront.

Ici, vous pouvez définir le premier plan de votre TabItem.Header ou de son contenu en vert, afin qu'il n'affecte pas les autres contenus du TabItem. Sinon, vous pouvez inverser la solution.

Else Essayez ceci:

<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

Merci Veer, mais comment puis-je définir la couleur de la police d'en-tête Tabitem sans définir le contenu? Je comprends le nom de cible, mais j'ai essayé quelques manières différentes sans joie. Je continue d'obtenir une erreur indiquant que le premier plan ne peut pas être défini sur un en-tête tabitem. – Adrian

+0

@Adrian: Attribuez un nom au panneau de la pile dans l'en-tête et utilisez-le dans le nom de la cible. – Amsakanna

+0

@Veer. Désolé d'être une douleur, mais j'ai essayé et je ne pouvais pas le faire fonctionner. Peut-être que je le fais mal (probablement!). Pouvez-vous poster du code pour me montrer? Merci – Adrian

3

C'est assez vieux, mais je suis tombé sur elle tout en cherchant une réponse à un problème similaire, et j'ai trouvé les réponses fournies pas du tout utile. Voici comment j'ai réparé ceci.

Si vous modifiez le ContentPresenter à un TextBlock dans le modèle de contrôle de votre TabItem, comme ceci:

....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.... 

ensuite dans votre déclencheur sur ce modèle de commande que vous spécifiez le targetname dans le trigger..ie 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 ... 

Cela devrait vous donner le texte en vert lorsque l'onglet est sélectionné, et non vert toutes les autres fois, tout en laissant la coloration texte dans le reste de l'application seule.

9

Je viens de rencontrer ce même problème, et après avoir bidouillé un peu, je pense avoir trouvé une solution plus élégante. Je dis plus élégant car il laisserait le ContentPresenter intact, et appliquerait les setters de premier plan et de poids de la police au TextElement du ContentPresenter (qui est fondamentalement une propriété attachée, mais c'est à côté du point). Le principal avantage de cette approche est que le remplacement du ContentPresenter par un TextBlock suppose implicitement que l'en-tête ne contiendra que du texte, ce qui limite l'utilisabilité de la solution de contournement et produit un code moins robuste. Si vous laissez le ContentPresenter en place, tout contenu, par ex. images + texte.

une chose que vous avez à faire est le nom de votre 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>... 

Maintenant, le premier plan et FontWeight ne seront pas héritées par le contenu du TabItem (testé).

Enjoy :)

+2

Merci Gilad, c'est définitivement une bien meilleure solution. Laisser le ContentPresenter intact est définitivement la solution. – thornhill

+0

Je viens de mettre cet exemple ensemble. Cependant les setters pour 'TextElement.Foreground' et' TextElement.FontWeight' n'a aucun effet. Si j'ajoute le nom 'grid' pour Grid puis que j'ajoute' ', son fond devient rouge. –

3

Malheureusement, si vous définissez le premier plan (ou FontWeight) sur un ContentPresenter par un déclencheur, vous assumez toujours que l'en-tête ne contiendra texte.

Si vous définissez Header = "SomeHeaderName" (c'est-à-dire uniquement du texte), ContentPresenter génère un TextBlock pour héberger ce texte d'accompagnement; le ContentPresenter sera le parent (logique) de ce TextBlock et ainsi, le nouveau Jeu de premier plan sur ContentPresenter sera hérité par ce TextBlock. Cela fonctionne bien. Toutefois, si l'en-tête est affecté à une partie de l'arborescence visuelle, comme un StackPanel horizontal avec une Image et un TextBlock (ou même un seul TextBlock), le parent logique du StackPanel est le TabItem et non le ContentPresenter. L'héritage fonctionne via l'arbre logique et ainsi le TextBlock à l'intérieur du StackPanel héritera à nouveau de son Foreground du TabItem; le premier plan défini sur le ContentPresenter n'a aucun effet sur celui-ci.

Une solution possible: un DataTemplate est finalement appliqué à un ContentPresenter, de sorte que le TemplatedParent de la racine du DataTemplate est ContentPresenter; et l'héritage fonctionne aussi à travers une barrière TemplatedParent-Child. Ainsi, si vous êtes en mesure de définir TabItem.HeaderTemplate à la place de TabItem.Header, alors pouvez définir le premier plan sur le ContentPresenter de l'en-tête, car la racine de HeaderTemplate héritera de Foreground du ContentPresenter. Le contenu SelectedContent, cependant, ne sera pas parce que le Foreground n'est pas défini sur le TabItem (et le contenu hérite de son premier plan à partir du TabItem).

Espérons que cela aide!

Questions connexes