Chronicide
Chronicide

Reputation: 1152

How can I set a custom Controltemplate as the default for whole application?

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>

Menu 1

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:

Menu 2

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

Answers (2)

BrainSlugs83
BrainSlugs83

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

Gordon Allocman
Gordon Allocman

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

Related Questions