2009-03-20 22 views
50

Supponiamo di avere una struttura di elemento nidificato, ad esempio, un ContextMenu con MenuItems:Styling elementi annidati in WPF

<ContextMenu Style="{StaticResource FooMenuStyle}"> 
    <MenuItem Style="{StaticResource FooMenuItemStyle}"/> 
    ... 
</ContextMenu> 

Si può facilmente applicare stili o modelli agli elementi ContextMenu o MenuItem. Ma se lo stile MenuItem appartiene allo stile Menu è piuttosto ingombrante e ridondante per aggiungerlo a ogni elemento MenuItem.

C'è un modo per applicarli automaticamente agli elementi figlio? In modo che si può semplicemente scrivere questo:

<ContextMenu Style="{StaticResource FooMenuStyle}"> 
    <MenuItem/> 
    ... 
</ContextMenu> 

Sarebbe pulito se FooMenuStyle potesse lo stile contenente elementi MenuItem, ma che non sembra essere possibile.

Modifica: L'esempio di menu è probabilmente fuorviante poiché non ero a conoscenza di ItemContainerStyle e l'intento era per una soluzione generale. Sulla base delle due risposte sono venuto su con due soluzioni: una variante generale e uno per ItemContainerStyle e simili:

<Style x:Key="FooMenuItem" TargetType="{x:Type MenuItem}"> 
    ... 
</Style> 

<Style x:Key="FooMenu" TargetType="{x:Type ContextMenu}"> 
    <!-- Variant for specific style attribute --> 
    <Setter Property="ItemContainerStyle" 
      Value="{StaticResource FooMenuItem}"/> 

    <!-- General variant --> 
    <Style.Resources> 
     <Style TargetType="{x:Type MenuItem}" 
       BasedOn="{StaticResource FooMenuItem}"/> 
    </Style.Resources> 
</Style> 

<ContextMenu Style="{StaticResource FooMenu}"> 
    <MenuItem/> 
</ContextMenu> 

risposta

17
<ContextMenu> 
    <ContextMenu.Resources> 
     <Style TargetType="{x:Type MenuItem}"> 
     <!--Setters--> 
     </Style> 
    </ContextMenu.Resources> 
    <MenuItem/> 
    <!--Other MenuItems--> 
</ContextMenu> 

Lo stile verrà applicato a tutti gli oggetti MenuItem all'interno del ContextMenu.

+4

Credo che abbia già uno stile nelle sue risorse e vorrei applicare a oggetti figlio, non re-dichiararlo di nuovo. –

+0

Inoltre, può essere espresso più chiaramente utilizzando ItemContainerStyle. –

+0

È possibile dichiarare un nuovo stile derivato da uno stile precedente. –

6
<ContextMenu ItemContainerStyle="{StaticResource FooMenuItemStyle}"> 
    <MenuItem/> 
</ContextMenu> 
+0

Penso che il mio esempio di menu fosse un po 'fuorviante (dato che non conoscevo ItemContainerStyle) e l'intento iniziale era per elementi arbitrari. Ma dal momento che ho effettivamente un menu questa è la strada da percorrere. – gix

121

Giusto per completare la risposta originale, penso che sia più chiaro aggiungendo lo stile nidificato all'interno del genitore così:

<Style x:Key="WindowHeader" TargetType="DockPanel" > 
    <Setter Property="Background" Value="AntiqueWhite"></Setter> 
    <Style.Resources> 
     <Style TargetType="Image"> 
      <Setter Property="Margin" Value="6"></Setter> 
      <Setter Property="Width" Value="36"></Setter> 
      <Setter Property="Height" Value="36"></Setter> 
     </Style> 
     <Style TargetType="TextBlock"> 
      <Setter Property="TextWrapping" Value="Wrap"></Setter> 
     </Style> 
    </Style.Resources> 
</Style> 
+6

Questa è la risposta più appropriata. No dove sul web si può andare bene. Sei forte! Grazie. – Rohit

+2

Grazie, questa informazione è davvero difficile da trovare. –

+0

Ho usato questo esempio per aiutarmi ad applicare uno stile a tutti i blocchi di testo annidati all'interno di un suggerimento, impostando una larghezza massima e rafforzando il wrapping in modo che i messaggi lunghi siano formattati meglio. – sfuqua