如何将自定义 Controltemplate 设置为整个应用程序的默认值?

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

我决定尝试自定义 Menu 和 MenuItem 的默认控件模板的许多方面。在 Visual Studio 中,我选择了我的菜单,在 属性 面板中找到 'Template',然后选择 'Convert to New Resource...'。

我对 MenuItem 做了同样的事情。然后,为了测试,我将 MenuItem SubMenuBorder 颜色更改为红色。此时,我有一个包含两个 ControlTemplate 的资源字典和一个如下所示的菜单:

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

问题是红色边框只会出现在我将模板明确设置为修改后的 CustomMenuItemControlTemplate 的 MenuItems 上。如果我想在所有菜单项上使用我的模板,我必须包括:

Template="{DynamicResource CustomMenuItemControlTemplate}"

...在我整个应用程序中的每个 MenuItem 上。

所以,接下来我想我应该有一个适用于所有 MenuItem 的样式,并使用 setter 来设置我的默认模板:

<Style TargetType="MenuItem">
    <Setter Property="Template" Value="{DynamicResource CustomMenuItemControlTemplate}" />
</Style>

这有效(注意所有子菜单上的红色边框),但出于某种原因,它极大地改变了菜单的外观:

在 setter 中,我尝试同时使用 DynamicResource 和 StaticResource 绑定,结果相同。

所以,我的主要问题是:有没有一种方法可以使用自定义 ControlTemplate 作为默认值,这样我就不必在每个控件上显式设置它?次要问题:为什么使用样式设置模板 属性 会导致它的外观发生如此剧烈的变化?

回答你的第一个问题:

如果您将 ControlTemplate 放入 app.xaml 的资源字典中,它将应用于整个应用程序。您的控件模板 header 应该是这样的:

<ControlTemplate TargetType="MenuItem" ...(other properties)>

这将使所有 MenuItem 控件隐式使用该控件模板。

回答你第二个问题:

出现这种情况是因为添加样式会覆盖默认样式,基本上会删除所有 built-in 样式。如果您希望样式仅更改一些内容,样式标签应如下所示:

<Style BasedOn="{StaticResource {x:Type MenuItem}}" ...(other properties)>

这样它就继承了所有的常规样式,只是更改了您明确定义的样式

所以不能放没有key的控件模板,而且WPF中key不能{x:Type ...}

但是您可以放置​​一个 Style 而不带键,该样式将成为默认样式。 -- 并且在那个样式中,你可以设置控件模板。

<Style TargetType="{x:Type MenuItem}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type MenuItem}">
                <!-- Insert Control Template Here -->
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>