如何覆盖全局样式(没有 x:Key),或者将命名样式应用于所有以类型为目标的控件?

Posted

技术标签:

【中文标题】如何覆盖全局样式(没有 x:Key),或者将命名样式应用于所有以类型为目标的控件?【英文标题】:How to override a global style (that doesn't have an x:Key), or alternatively apply a named style to all type-targeted controls? 【发布时间】:2010-11-21 04:15:41 【问题描述】:

我声明了一种样式,我想将其应用于项目中的所有按钮,该样式位于 ResourceDictionary 中:

<Style TargetType="StackPanel">
    <Setter Property="Orientation" Value="Horizontal" />
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
</Style>

现在,在某个窗口中,我想继承此样式但添加一个值:

<Style TargetType="StackPanel"> 
    <Setter Property="Margin" Value="5"/>
</Style>

问题是它没有从全局样式继承,为了继承我必须为全局样式分配一个键:

<Style TargetType="StackPanel" x:Key="StackPanelStyle" />

然后在窗口的 XAML 中继承(或/和覆盖 - 可选)它:

<Style TargetType="StackPanel" BasedOn="StackPanelStyle" />

问题是如果你分配一个键,它不是全局的,你必须在每个窗口/范围内调用它。

我的问题的解决方案应该是两者之一(我还有什么遗漏的吗?):

    具有带键的全局样式,该样式会自动应用于整个应用程序中的所有目标控件。 一种在没有和覆盖它的情况下引用 ResourceDictionary 级别的未命名样式的方法。

我考虑过在命名样式(在 ResourceDictionary 中)附近重新声明实际有效的样式:

<!--In the ResourceDictionary-->
<Style x:Key="StackPanelStyle" TargetType="StackPanel">
    <Setter Property="Orientation" Value="Horizontal" />
    <Setter Property="VerticalAlignment" Value="Center"/>
    <Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<!--In the app.xaml-->
<Style TargetType="StackPanel" BasedOn="StaticResource StackPanelStyle"/>
<!--In the window/page scope-->
<Style TargetType="StackPanel" BasedOn="StaticResource StackPanelStyle"/

但我正在寻找比愚蠢地重新声明所有样式更好的东西。

【问题讨论】:

【参考方案1】:

在全局资源字典的某个地方,您可以使用键定义基本样式。此基本样式针对的类型是您打算应用该样式的所有类型的基础。然后根据上述基本样式定义针对您想要的类型的样式。

<Style
    x:Key="upDownBaseStyle"
    TargetType="x:Type Control">
    <Setter
      Property="Margin"
      Value="2" />
    <Setter
      Property="HorizontalAlignment"
      Value="Stretch" />
    <Setter
      Property="VerticalAlignment"
      Value="Center" />
  </Style>

  <Style
    TargetType="x:Type xceed:IntegerUpDown"
    BasedOn="StaticResource upDownBaseStyle">
  </Style>

  <Style
    TargetType="x:Type xceed:DoubleUpDown"
    BasedOn="StaticResource upDownBaseStyle">
  </Style>

现在最后两种样式应用于应用程序中的所有 IntegerUpDown 和 DoubleUpDown 控件,而无需提及任何键。

因此,基本规则:基本样式必须具有引用它的键,而派生样式可能没有,因此它们可以在没有任何键的情况下应用 - 只能通过目标类型。

【讨论】:

【参考方案2】:

我建议您在这里寻找的主要风格或行为场景通常是通过创建用户控件来实现的。如果您要创建一个应用了“全局”样式的新按钮控件,那么在您使用该控件的任何地方,您都可以简单地添加任何“”样式或在需要时覆盖样式.

如果您还没有创建用户控件,它们很容易实现。

【讨论】:

【参考方案3】:

试试这个:

<Style TargetType="x:Type StackPanel" BasedOn="StaticResource x:Type StackPanel">
  <!-- ... -->
</Style>

我已经在 App.xaml 的 ResourceDictionary 中声明了我的基本样式,如果我在这样的特定窗口中覆盖它们,它通常可以工作。

【讨论】:

谢谢哥们,简短、快速、准确! Silverlight 中的这个怎么样? @MSNetDev 我不使用 Silverlight,但据我所知,它也应该在那里工作。 我想知道我们怎样才能得到这个:BasedOn="StaticResource x:Type StackPanel。silverlight 不支持 x:Type。 这个解决方案对我不起作用,除非我设置 x:Key:&lt;Style TargetType="x:Type StackPanel" BasedOn="StaticResource x:Type StackPanel" x:Key="MyStackPanel"&gt;。有没有不设置 x:Key 的解决方案?

以上是关于如何覆盖全局样式(没有 x:Key),或者将命名样式应用于所有以类型为目标的控件?的主要内容,如果未能解决你的问题,请参考以下文章

如果没有给定 x:Key,样式设置器将无法工作

React 组件样式被全局样式覆盖

react覆盖组件样式的3种方法

网页中 需要不同的hover样式 如何设置不同的hover样式 怎么去命名 哪一个种全局 哪一个

React Antd 中如何修改覆盖默认样式及样式引用

React Antd 中如何修改覆盖默认样式及样式引用