【问题标题】:WPF Grid.Resources Style breaks ResourceDictionary Style. How to make them coexist?WPF Grid.Resources 样式会破坏 ResourceDictionary 样式。如何让它们共存?
【发布时间】:2011-08-19 14:12:09
【问题描述】:

在 WPF 应用程序中,我有一个 ResourceDictionary 和为 TargetType MyCustomControl 定义的 Style

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:cc="clr-namespace:MyControlLibrary;assembly=MyControlLibrary" >

  <Style TargetType="{x:Type cc:MyCustomControl}"> 
    <Setter Property="Prop1" Value="1" />
    <Setter Property="Prop2" Value="2" />
    ...

问题是我需要在 XAML 页面中为 MyCustomControl 定义一个上下文菜单,如下所示:

   <Grid>
     <Grid.Resources>
           <ContextMenu x:Key="MyControlContextMenu">
               <MenuItem Name="Name1" 
                         Header="Header1" 
                         Click="Cm1_Click"
                         .../>                   
                ....
            </ContextMenu>
       <Style TargetType="{x:Type ScNamespace:MyCustomControl}">
         <Setter Property="ContextMenu" Value="{StaticResource MyControlContextMenu}"/>
       </Style>
     </Grid.Resources>
   ...

在这种情况下,虽然我只在网格内的样式定义中分配了一个属性,但根本不应用 ResourceDictionary 样式值。它们被页面资源样式覆盖并被忽略。

如何解决这个问题?也许有一种方法可以在 Grid.Resources 部分中引用 ResourceDictionary 以强制查找 ResourceDictionary 样式?

【问题讨论】:

  • 您在哪里定义/包含第一个 ResourceDictionary?
  • @CodeNaked 在 App.xaml 中作为 Application.ResourcesResourceDictionary.MergedDictionaries

标签: wpf xaml resources resourcedictionary


【解决方案1】:

不确定它是否是您正在寻找的,但样式可以从另一个继承。使用BasedOn-属性,您可以定义Style 的基本样式,以便新样式继承此样式的所有设置。

但是,如果BasedOn 引用相同的键(类型),我从未尝试过它是否也有效。也许它有效:

<Style TargetType="{x:Type ScNamespace:MyCustomControl}" 
       BasedOn="{x:Type ScNamespace:MyCustomControl}">

如果这不起作用,也许您可​​以将Style 分开,用一个键全局定义它,然后通过BasedOn-property 引用全局定义的样式。

【讨论】:

  • 是的,这个想法是正确的,尽管在这种实现方式中它不起作用。不过,感谢您首先给出方向。 +1
【解决方案2】:

基于默认样式的新样式:

<Style TargetType="{x:Type ScNamespace:MyCustomControl}" BasedOn="{StaticResource {x:Type ScNamespace:MyCustomControl}}">
    <Setter Property="ContextMenu" Value="{StaticResource MyControlContextMenu}"/>
</Style>

【讨论】:

    【解决方案3】:

    通常,控件的默认样式应在主题特定文件的主题文件夹中定义(有关详细信息,请参阅here)。

    当应用程序寻找 资源,它在三个层次上看 以下顺序:

    1) 元素级别。

    系统从元素开始 引用资源,然后 搜索逻辑资源 父级,依此类推,直到根 已到达元素。

    2) 应用层。

    应用程序定义的资源 对象。

    3) 主题级别。

    主题级词典存储在 一个名为 Themes 的子文件夹。中的文件 主题文件夹对应 主题。例如,您可能有 Aero.NormalColor.xaml, Luna.NormalColor.xaml, Royale.NormalColor.xaml 等等。 你也可以有一个文件名为 通用的.xaml。当系统看起来 对于主题级别的资源,它 首先在 特定于主题的文件,然后查找 它在 generic.xaml 中。

    在您的情况下,您有两个隐式样式,因此 HCL 和 Kent 的答案应该有效。因为一次只能应用一种隐式样式。直接正确设置样式也是如此。在这种情况下,不会应用任何隐式样式。

    如果您将第一个样式设置为主题级别的默认样式,那么它将应用于除了您的第二个隐式样式(或任何明确定义的样式)。

    【讨论】:

      猜你喜欢
      • 2017-05-26
      • 2019-03-09
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 2010-10-27
      • 1970-01-01
      • 2023-04-07
      • 2013-04-03
      相关资源
      最近更新 更多