简体   繁体   中英

overriding styles defined in generic.xaml results in merged style

I have a control with a style defined in a separate resource dictionary and use the generic.xaml magic to apply it.

If I understand the lookup mechanism described on msdn ( https://msdn.microsoft.com/de-de/library/ms750613%28v=vs.110%29.aspx ), the generic.xaml is used after the application resources, but adding a style for MyWindow will result in the style from generic.xaml + the style defined in App.xaml.

Here is my code:

Generic.xaml

<ResourceDictionary ...>
   <Style TargetType="{x:Type test:MyWindow}" BasedOn="{StaticResource ResourceKey={x:Type Window}}">
        <Setter Property="Background" Value="Gainsboro" />
        <Setter Property="Title" Value="Default!" />
   </Style>
</ResourceDictionary>

App.xaml

<Application.Resources>
     <ResourceDictionary>
         <Style TargetType="{x:Type test:MyWindow}" BasedOn="{StaticResource ResourceKey={x:Type Window}}">
            <Setter Property="Background" Value="HotPink" />
         </Style>
</Application.Resources>

The window will have a pink background (from the application.resource style) and "Default!" as title from the generic.xaml style.

Why doesn't wpf stop searching for a style at the application level?

This because default (theme) styles are treated differently from normal styles.

Consider the Dependency Property lookup precedence list :

  1. Property system coercion.
  2. Active animations.
  3. Local value.
  4. TemplatedParent properties. Triggers and property sets from the TemplatedParent.
  5. Implicit style. A special case for the Style property. Here, the Style property is filled by any style resource with a key that matches the type of that element. This lookup does not proceed into the themes .
  6. Style triggers. Triggers within styles from page or application.
  7. Template triggers.
  8. Style setters.
  9. Default (theme) style.
  10. Inheritance.
  11. Default value from dependency property metadata.

When WPF is deciding the value for MyWindow.Style , it goes through the precedence list and settles on using "5. implicit style" to assign it. So then it finds a matching style in App.xaml and uses that. If you inspect MyWindow's properties at runtime, you should indeed see that MyWindow.Style is set to the one from App.xaml. So, WPF actually does stop searching for a style at the application level.

It's just that because of the DefaultStyleKeyProperty , the default style is still there in the DependencyProperty lookup list, albeit at a lower precedence level than the App.xaml style.

In this case, the App.xaml doesn't set the Title property, so the DependencyProperty engine falls back to the default style in Generic.xaml to provide a value. So this is why you are getting that merged style behaviour.

Of course, note that this only happens when the Generic.xaml magic is set up properly .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM