2009-03-29 10 views
9

En <Window.Resources> he definido siguiente estilo:¿Es posible establecer un estilo en XAML que afecta selectivamente a los controles?

<Style x:Key="textBlockStyle" TargetType="TextBlock"> 
     <Setter Property="Margin" Value="5,0,5,0"/> 
    </Style> 

he definido algunos cuadrícula donde tengo cuatro TextBlocks:

<WrapPanel> 
     <TextBlock Style="{StaticResource textBlockStyle}">Server</TextBlock> 
     <TextBlock Style="{StaticResource textBlockStyle}">IP</TextBlock> 
     <TextBlock Style="{StaticResource textBlockStyle}">Port</TextBlock> 
     <TextBlock Style="{StaticResource textBlockStyle}">Status</TextBlock> 
    </WrapPanel> 

Problema: Necesito hacer referencia a los textBlockStyle cuatro veces.

Pregunta: ¿Es posible establecer ese estilo una sola vez en WrapPanel o en otro lugar sin repetir la referencia al estilo?

Tal vez algo como:

<WrapPanel Style="{StaticResource textBlockStyle}"> 
     <TextBlock>Server</TextBlock> 
     <TextBlock>IP</TextBlock> 
     <TextBlock>Port</TextBlock> 
     <TextBlock>Status</TextBlock> 
    </WrapPanel> 

No estoy buscando una solución global! Podría eliminar esa propiedad x:Key="textBlockStyle", pero eso afectaría a todosTextBlocks en la ventana. Necesito un mecanismo más selectivo, pero sin esa fea duplicación de código.

Respuesta

17

Tiene varias opciones, presentadas aquí en orden de qué tan bien se escalan.

Opción 1: Definir el estilo sin una llave en un nivel inferior

Usted puede pegar el recurso a nivel WrapPanel de modo que sólo afecta a los controles dentro de esa WrapPanel:

<WrapPanel> 
    <WrapPanel.Resources> 
     <Style TargetType="TextBlock"> 
      <Setter Property="Margin" Value="5,0,5,0"/> 
     </Style> 
    </WrapPanel.Resources> 

    <!-- TextBlocks here --> 
</WrapPanel> 

Aviso la falta de llave Este Style se aplicará a todos TextBlock s dentro del WrapPanel.

Opción 2: Definir el estilo con una clave y otra vez sin un nivel inferior

Si define el Style a un nivel superior con una llave, a continuación, puede definir otro Style a un nivel más bajo sin una llave, y la base que Style en el nivel más alto uno:

<Window> 
    <Window.Resources> 
     <Style TargetType="TextBlock" x:Key="textBlockStyle"> 
      <Setter Property="Margin" Value="5,0,5,0"/> 
     </Style> 
    </Window.Resources> 

    <WrapPanel> 
     <WrapPanel.Resources> 
      <Style TargetType="TextBlock" BasedOn="{StaticResource textBlockStyle"/> 
     </WrapPanel.Resources> 

     <!-- TextBlocks here --> 
    </WrapPanel> 
</Window> 

Esto resulta en una Style que se aplica automáticamente a TextBlock s dentro de la WrapPanel, pero no fuera de él. Además, no duplica los detalles del Style - se almacenan en un nivel superior.

Opción 3: Coloque los estilos en una ResourceDictionary y selectivamente fusionarla

Por último, puede colocar sus Style s en una separada ResourceDictionary y selectivamente fusionar ese diccionario en Resources colección de un control:

<!-- TextBlockStyles.xaml --> 
<ResourceDictionary> 
    <Style TargetType="TextBlock"> 
     <Setter Property="Margin" Value="5,0,5,0"/> 
    </Style> 
</ResourceDictionary> 

<!-- Window.xaml --> 
<Window> 
    <WrapPanel> 
     <WrapPanel.Resources> 
      <ResourceDictionary> 
       <ResourceDictionary.MergedDictionaries> 
        <ResourceDictionary Source="TextBlockStyles.xaml"/> 
       </ResourceDictionary.MergedDictionaries> 
      </ResourceDictionary> 
     </WrapPanel.Resources> 
    </WrapPanel> 
</Window> 

<!-- Alternative Window.xaml if you have only one RD to merge in --> 
<Window> 
    <WrapPanel> 
     <WrapPanel.Resources> 
      <ResourceDictionary Source="TextBlockStyles.xaml"/> 
     </WrapPanel.Resources> 
    </WrapPanel> 
</Window> 

Ahora puede tener tantos conjuntos de estilos definidos en diccionarios separados como desee, y luego aplicarlos selectivamente a su árbol de elementos.

+0

Normalmente prefiero la opción 2 si tengo el estilo ya definido y lo uso en otro lugar, de lo contrario, la opción 1. Por lo que vale. Gran respuesta Kent. –

2

yup, puedes hacer eso. Casi tienes la idea correcta. lo hace como esto ....

<WrapPanel> 
< WrapPanel. Resources > 
<Style TargetType="{x:Type TextBlock}"> 
     <Setter Property="Margin" Value="5,0,5,0"/> 
    </Style> 
</WrapPanel.Resources/> 
     <TextBlock Server</TextBlock> 
     <TextBlock >IP</TextBlock> 
     <TextBlock >Port</TextBlock> 
     <TextBlock >Status</TextBlock> 
    </WrapPanel> 

utilizando el {x: Tipo} sintaxis que no necesita la x: llave, que fijará el estilo de todos los bloques de texto en el WrapPanel. si desea estilos diff, puede usar la tecla x: y explicity establecer el estilo en el bloque de texto.

Cuestiones relacionadas