4
votes

In a WPF app I have a ResourceDictionary with Style defined for the TargetType MyCustomControl:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:cc="clr-namespace:MyControlLibrary;assembly=MyControlLibrary" >

  <Style TargetType="{x:Type cc:MyCustomControl}"> 
    <Setter Property="Prop1" Value="1" />
    <Setter Property="Prop2" Value="2" />
    ...

The problem is that I need to define a context menu for MyCustomControl in the page XAML like following:

   <Grid>
     <Grid.Resources>
           <ContextMenu x:Key="MyControlContextMenu">
               <MenuItem Name="Name1" 
                         Header="Header1" 
                         Click="Cm1_Click"
                         .../>                   
                ....
            </ContextMenu>
       <Style TargetType="{x:Type ScNamespace:MyCustomControl}">
         <Setter Property="ContextMenu" Value="{StaticResource MyControlContextMenu}"/>
       </Style>
     </Grid.Resources>
   ...

In this case, though I only assign one Property in the Style definition inside my Grid, the ResourceDictionary Style values are not applied at all. They get overridden by page resource style and ignored.

How to solve this issue? Maybe there is a way to make a reference to ResourceDictionary in the Grid.Resources section to enforce looking up the ResourceDictionary Style?

3
Where do you define/include the first ResourceDictionary?CodeNaked
@CodeNaked In the App.xaml as a Application.Resources in a ResourceDictionary.MergedDictionariesrem

3 Answers

4
votes

Base your new style on your default style:

<Style TargetType="{x:Type ScNamespace:MyCustomControl}" BasedOn="{StaticResource {x:Type ScNamespace:MyCustomControl}}">
    <Setter Property="ContextMenu" Value="{StaticResource MyControlContextMenu}"/>
</Style>
1
votes

Not sure if it is what you're looking for, but a Style can inherit from another. With the BasedOn-property you can define the base style of a Style, so that the new style inherits all settings from this style.

However I never tried if it works also if the BasedOn references to the same key (type). Maybe it works:

<Style TargetType="{x:Type ScNamespace:MyCustomControl}" 
       BasedOn="{x:Type ScNamespace:MyCustomControl}">

If this works not, maybe you can separate the Style, define it globaly with a key and then reference to the globaly defined Style via the BasedOn-property.

1
votes

In general, Controls should have their default Styles defined in the Themes folder in a theme specific file (see here for more info).

When an application looks for a resource, it looks at three levels in the following order:

1) The element level.

The system starts with the element that references the resource and then searches resources of the logical parent and so forth until the root element is reached.

2) The application level.

Resources defined by the Application object.

3) The theme level.

Theme-level dictionaries are stored in a subfolder named Themes. The files in the Themes folder correspond to themes. For example, you might have Aero.NormalColor.xaml, Luna.NormalColor.xaml, Royale.NormalColor.xaml, and so on. You can also have a file named generic.xaml. When the system looks for a resource at the themes level, it first looks for it in the theme-specific file and then looks for it in generic.xaml.

In your case, you have two implicit Styles, so HCL and Kent's answers should work. Since only one implicit Style can be applied at a time. Same goes for setting the Style properly directly. In that case, no implicit Styles will be applied.

If you have your first Style setup as a default Style at the theme level, then it would be applied in addition to your second implicit Style (or any explicitly defined Style).