2010-06-21 13 views
12

Tengo un control de tabulación que he rediseñado. El TabItem tiene un disparador que se dispara cuando se selecciona TabItem que cambia el texto de TabItem a negrita y verde. El problema que tengo es que el texto en el contenido de la pestaña también se establece en negrita y verde.Configuración del color de primer plano de TabItem también establece el color de primer plano de TabControl

Puedo solucionar esto configurando todos mis controles en el contenido de la pestaña para que sean del color y el peso que deseo de la fuente, pero ¿debo hacerlo? Por lo tanto, debo asegurarme de que cada bloque de texto en el área de contenido tenga un estilo que establezca el color en negro y el peso normal de la fuente.

¿Cómo puedo configurar la parte IsSelected del TabItem para que se muestre en verde, pero dejo solo el contenido de la pestaña?

He intentado establecer el primer plano de TabControl en negro, pero esto no funciona.

Verá en el siguiente ejemplo de código que el texto en la primera pestaña es verde, y quiero que sea negro, pero sin configurar cada control en el contenido de la pestaña.

Ejemplo de código a continuación:

<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

¡Publica un código para descubrir qué está mal! – decyclone

+0

Se agregó muestra de código según lo solicitado. – Adrian

Respuesta

0

Todos los controles en WPF hereda las propiedades de su padre. Como el color de TabItem era negro, su hijo textblock también era de color negro. Ahora que ha cambiado todo el color de primer plano de TabItem a verde, todos sus hijos lo heredarán.

Aquí puede establecer el primer plano de su TabItem.Header o sus contenidos en verde, para que no afecte a otros contenidos en el TabItem. De lo contrario, puedes invertir la solución.

Else Prueba esto:

<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

Gracias Veer, pero ¿cómo configuro el color de la fuente del encabezado tabitem sin configurar los contenidos? Entiendo el nombre de destino, pero lo he intentado de diferentes maneras sin alegría. Sigo recibiendo un error que indica que el primer plano no se puede establecer en un encabezado de tabitem. – Adrian

+0

@Adrian: asigne un nombre al panel de la pila dentro del encabezado y úselo en el nombre del objetivo. – Amsakanna

+0

@Veer. Lamento ser un dolor, pero lo intenté y no pude lograr que funcionara. Tal vez lo estoy haciendo mal (¡probable!). ¿Puedes publicar un código para mostrarme? Gracias – Adrian

3

Esto es bastante viejo, pero me encontré con que en la búsqueda de una respuesta para un problema similar, y encontré las respuestas suministradas No fue útil. Así es como lo arreglé.

Si cambia el ContentPresenter a un TextBlock en la plantilla de control de su TabItem, así:

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

Luego, en su disparador en esa plantilla de control que especifique el TargetName en el 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 ... 

que debe darle el texto en verde cuando se selecciona la pestaña, y no verdes todas las otras veces, dejando el color del texto en el resto de la aplicación solo.

9

Acabo de encontrarme con este mismo problema, y ​​después de jugar con él un poco creo que he encontrado una solución más elegante.

Estoy diciendo que es más elegante, ya que dejaría intacto el ContentPresenter y aplicaría los setters de primer plano y fontweight al TextElement de ContentPresenter (que básicamente es una propiedad adjunta, pero eso está al lado).

La principal ventaja de este enfoque es que al reemplazar el ContentPresenter con un TextBlock se asume implícitamente que el encabezado solo contendrá texto, lo que limita la usabilidad de la solución y produce un código menos robusto. Al dejar el ContentPresenter en su lugar, se permitirá cualquier contenido, p. imágenes + texto.

Una cosa más que tendría que hacer es nombrar a su 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>... 

Ahora el primer plano y FontWeight no serán heredados por el contenido de la TabItem (probado).

Enjoy :)

+2

Gracias Gilad, definitivamente es una solución mucho mejor. Dejar intacto el ContentPresenter es definitivamente el camino a seguir. – thornhill

+0

Acabo de poner este ejemplo en conjunto. Sin embargo, los ajustadores para 'TextElement.Foreground' y' TextElement.FontWeight' no tiene ningún efecto. Si agrego el nombre 'grid' para Grid y luego agrego' ', su fondo se vuelve rojo. –

3

Por desgracia, si se establece el primer plano (o FontWeight) en un ContentPresenter por algún disparador, todavía asumen que la cabecera sólo contendrá texto.

Si establece Header = "SomeHeaderName" (es decir, solo texto), ContentPresenter generará un TextBlock para alojar este texto de cabecera; el ContentPresenter será el padre (lógico) de este TextBlock y, por lo tanto, el nuevo conjunto de primer plano en el ContentPresenter será heredado por este TextBlock. Esto funciona bien

Sin embargo, si al Encabezado se le asigna una parte del árbol visual, como un StackPanel horizontal con una Imagen y un TextBlock (o incluso un TextBlock), el elemento primario lógico del StackPanel es el TabItem y no el ContentPresenter. La herencia funciona a través del árbol lógico, por lo que TextBlock dentro de StackPanel finalmente heredará su primer plano del TabItem nuevamente; el primer plano establecido en ContentPresenter no tiene ningún efecto sobre esto.

Una posible solución: un DataTemplate finalmente se aplica a un ContentPresenter, por lo que el TemplatedParent de la raíz de DataTemplate es el ContentPresenter; y la herencia funciona a través de una barrera TemplatedParent-Child también. Entonces, si puede establecer TabItem.HeaderTemplate en lugar de TabItem.Header, entonces puede configurar el primer plano en el ContentPresenter del encabezado, porque la raíz de HeaderTemplate heredará el primer plano de ContentPresenter. Sin embargo, SelectedContent no lo hará porque el primer plano no está configurado en el TabItem (y el contenido hereda su primer plano del TabItem).

Espero que esto ayude!

Cuestiones relacionadas