如何将自定义 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>
我决定尝试自定义 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>