Application.Resources与Window.Resources中的隐式样式?

Rac*_*hel 34 wpf resources

我一直在寻找这个问题,发现放置一个含蓄TextBlock的风格Application.Resources是风格适用于所有的TextBlocks,即使是那些内如其他控件Buttons,ComboBoxes等等

<Application.Resources>
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="Foreground" Value="Blue" />
    </Style>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

配售隐含的风格Window.Resources 不交叉控制模板的界限,所以像ButtonsComboBoxes维持其默认的黑色文本.

<Window.Resources>
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="Foreground" Value="Blue" />
    </Style>
</Window.Resources>
Run Code Online (Sandbox Code Playgroud)

此外,在其中添加默认样式Application.Resources使其无法用另一种隐式样式覆盖该样式.

<!-- Doesn't work if implicit style with same property is in Application.Resources -->
<ComboBox.Resources>
    <Style TargetType="{x:Type TextBlock}">
        <Setter Property="Foreground" Value="Red" />
    </Style>
</ComboBox.Resources>
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 为什么是这样?
  • Application.Resources和之间是否还有其他差异Windows.Resources
  • 何时应该使用一个而不是另一个?

    我理解这Application.Resources适用于整个应用程序,Window.Resources只适用于窗口,但我想知道为什么样式Application处理方式不同于样式Window

Cod*_*ked 24

这实际上是添加到WPF的唯一特殊处理,它是通过设计完成的.实现它的代码可以FrameworkElement在方法中找到FindImplicitStyleResource,它有效地执行:

internal static object FindImplicitStyleResource(FrameworkElement fe, object resourceKey, out object source)
{
        // ...
        DependencyObject boundaryElement = null;
        if (!(fe is Control))
            boundaryElement = fe.TemplatedParent;
        // ...
}
Run Code Online (Sandbox Code Playgroud)

所以经验法则是隐式样式总是应用于控件(即派生自Control).假设可以找到隐式Style.

对于在使用的元素ControlTemplate不从派生Control,比如TextBlock,隐式的查找不会越过它的模板父.在你的情况下,这将是ComboBox.

我相信这样做是为了使非应用程序隐式的TextBlock样式不会无意中应用于TextBlock控件模板中使用的元素,开发人员可能会或可能不会知道这些元素.隐式样式只会应用于开发人员在自己的XAML中实际创建的TextBlocks.

应用程序隐式样式仍然允许全局样式,例如增加字体大小.但可能造成了更多的混乱而不是它的价值.

没有什么好的答案可以说明何时使用它们,因为它们各自都有它们的功能.显然,如果您不想影响TextBlock应用程序中的每个应用程序,则不应将样式放在应用程序资源中.

但请记住,这会影响任何非Control元素,例如Shape元素.