Reputation: 1152
I have decided to look at trying to customize a number of aspects of the default control template for Menu and MenuItem. In Visual Studio, I selected my Menu, found 'Template' in the property panel, and chose 'Convert to New Resource...'.
I did the same thing for MenuItem. Then, just to test, I changed the MenuItem SubMenuBorder color to red. At this point, I had a resource dictionary with the two ControlTemplates, and a Menu that looked like this:
<Menu Template="{DynamicResource CustomMenuControlTemplate}">
<MenuItem Header="File" Template="{DynamicResource CustomMenuItemControlTemplate}">
<MenuItem Header="Test 1" />
<MenuItem Header="Test 2">
<MenuItem Header="Subtest 1" />
<MenuItem Header="Subtest 2" />
<MenuItem Header="Subtest 3" />
</MenuItem>
<MenuItem Header="Test 3" />
</MenuItem>
</Menu>
The issue is that the red border will only appear on MenuItems where I explicitly set the Template to my modified CustomMenuItemControlTemplate. If I want to have my template used on all menu items, I would have to include:
Template="{DynamicResource CustomMenuItemControlTemplate}"
...on every MenuItem in my entire application.
So, next I thought that I'd have a style that applies to all MenuItems, and use a setter to set my default template:
<Style TargetType="MenuItem">
<Setter Property="Template" Value="{DynamicResource CustomMenuItemControlTemplate}" />
</Style>
This works (note the red borders on all sub-menus), but for some reason, it drastically changes how the menus look:
In that setter, I tried using both DynamicResource and StaticResource bindings, with the same results.
So, my main question: Is there a way to use a custom ControlTemplate as the default, so that I don't have to explicitly set it on each control? Secondary question: Why does using a style to set the template property cause such drastic changes to how it looks?
Upvotes: 4
Views: 2700
Reputation: 6411
So you can't put a control template without a key, and the key can't be {x:Type ...}
in WPF.
But you can put a Style
without a key, and that style will be the default. -- And in that style, you can set the control template.
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type MenuItem}">
<!-- Insert Control Template Here -->
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Upvotes: 4
Reputation: 778
To answer your first question:
If you put the ControlTemplate in your app.xaml's resource dictionary, it will be applied across your entire application. Your control template header should have something like this:
<ControlTemplate TargetType="MenuItem" ...(other properties)>
This will make all MenuItem controls implicitly use that control template.
To answer you second question:
This occurs because adding a style overrides the default style, essentially removing all built-in styling. If you want the style to only change a few things the style tag should look like this:
<Style BasedOn="{StaticResource {x:Type MenuItem}}" ...(other properties)>
This way it inherits all the normal styling and just changes the styles you explicitly define
Upvotes: 2