Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Styling nested elements in WPF

Suppose you have a nested element structure, for example a ContextMenu with MenuItems:

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

You can easily apply styles or templates to the ContextMenu or MenuItem elements. But if the MenuItem style belongs to the Menu style it is quite cumbersome and redundant to add it to every MenuItem element.

Is there any way to apply those automatically to child elements? So that you can simply write this:

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

It would be neat if FooMenuStyle could style containing MenuItem elements, but that does not seem to be possible.

Edit: The Menu example is probably misleading since I was unaware of ItemContainerStyle and the intent was for a general solution. Based on the two answers I have come up with two solutions: one general variant and one for ItemContainerStyle and the like:

<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>
like image 968
gix Avatar asked Mar 20 '09 14:03

gix


3 Answers

Just to complete the original answer, I think it is clearer adding the nested style inside the parent like that:

<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>
like image 175
Juan Calero Avatar answered Oct 17 '22 20:10

Juan Calero


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

The style will be applied to all MenuItem objects within the ContextMenu.

like image 29
Josh G Avatar answered Oct 17 '22 18:10

Josh G


<ContextMenu ItemContainerStyle="{StaticResource FooMenuItemStyle}">
    <MenuItem/>
</ContextMenu>
like image 5
Kent Boogaart Avatar answered Oct 17 '22 20:10

Kent Boogaart