开发者

WPF Grid.Resources Style breaks ResourceDictionary Style. How to make them coexist?

开发者 https://www.devze.com 2023-03-02 22:17 出处:网络
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\"

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开发者_StackOverflow中文版 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?


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>


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.


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

0

精彩评论

暂无评论...
验证码 换一张
取 消