scobi
scobi

Reputation: 14548

How to make a WPF style inheritable to derived classes?

In our WPF app we have a global style with TargetType={x:Type ContextMenu}. I have created a MyContextMenu that derives from ContextMenu, but now the default style does not apply.

How can I tell WPF that I want MyContextMenu to inherit the default style from ContextMenu? Hopefully I can do this from within my control itself (via static ctor metadata override or something?) and not have to mess around in any xaml.

Upvotes: 24

Views: 5963

Answers (2)

Jean-David Lanz
Jean-David Lanz

Reputation: 1013

In complement to CodeNaked's excellent suggestions, I tried specifying Style in the XAML part of MyContextMenu:

<ContextMenu x:Class=LocalProject.MyContextMenu"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:AdelSoft_WS_FRA_Test.Composants"
             mc:Ignorable="d"
             Style="{DynamicResource {x:Type ContextMenu}}">

The compiler warned me that it cannot resolve the resource, but at runtime it looks quite able to.

Naturally, you can also use

             Style="{StaticResource ContextMenuStyleName}">

if you use style names.

Upvotes: -1

CodeNaked
CodeNaked

Reputation: 41393

If you have a Style defined in your application like so:

<Style TargetType="{x:Type ContextMenu}" ...

Then that is an implicit Style, not a default Style. Default Styles are generally located in the same assembly as the control or in matching assemblies (i.e. MyAssembly.Aero.dll).

Implicit Styles are not automatically applied to derived types, which is probably what you are seeing.

You can either define a second Style, like so:

<Style x:Key="{x:Type ContextMenu}" TargetType="{x:Type ContextMenu}" ...
<Style TargetType="{x:Type local:MyContextMenu}" BasedOn="{StaticResource {x:Type ContextMenu}}" ...

Or you can leverage the Style property of your control. You could do the following from XAML

<local:MyContextMenu Style="{DynamicResource {x:Type ContextMenu}}" ...

or you can do this in your MyContextMenu like so:

public MyContextMenu() {
    this.SetResourceReference(StyleProperty, typeof(ContextMenu));
}

Upvotes: 63

Related Questions