ResourceDictionary的Windows样式不适用

时间:2013-03-15 09:09:47

标签: c# wpf xaml styles

由于我的申请中有多个Window,我正在寻找一种解决方案,不需要我在每个binding上设置Window

我创建了一个ResourceDictionary,其窗口背景为style

<Style TargetType="{x:Type Window}">
    <Setter Property="Background" Value="AliceBlue"/>
</Style>

在我的XAML中,我设置了ResourceDictionary

<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Templates.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>

没有错误,但我的Window颜色保持白色。

3 个答案:

答案 0 :(得分:31)

这似乎是由WPF从嵌套ResourceDictionary加载/处理样式的顺序与Window类的细节的组合引起的。

假设根据您的帖子定义MainWindow。现在将以下内容放在Templates.xaml

<Style TargetType="{x:Type Window}">
    <Setter Property="Background" Value="Red"/>
</Style>
<Style TargetType="{x:Type Window}" x:Key="myStyle">
    <Setter Property="Background" Value="Green"/>
</Style>

如果MainWindow没有定义样式,那么您将在设计器中看到它以红色背景显示。设计人员正在解析整个Xaml并加载资源字典,然后绘制结果。在绘制窗口之前读取样式,因此应用红色背景。

运行应用程序时,会在应用ResourceDictionary之前创建窗口。它会在处理嵌套x:Key="{x:Type Window}"之前查找默认样式(带有ResourceDictionary的样式,并且不会找到任何内容。因此,在运行时,窗口将显示默认颜色。 (这是上面评论中描述的行为。)请记住,x:Key="{x:Type Window}"的样式具有与Windows样式匹配的默认值。

如果您明确使用myStyle,则可以证明这一点。如果您将Window定义添加到属性Style="{StaticResource myStyle}",您会发现设计器失败,但您也会收到运行时错误,因为尚未创建myStyle窗口需要它的时间。如果您切换到Style="{DynamicResource myStyle}",那么您会看到它按预期工作,因为DynamicResource会在解析ResourceDictionary并包含样式后更新。

因此,应用此功能,您可以通过将此问题添加到Window元素来解决问题:Style="{DynamicResource {x:Type Window}}" - 但这很复杂。更好的解决方案是将您的资源字典包含在app.xaml文件中,在打开任何窗口之前将其解析,从而可供所有人使用:

<Application.Resources>
    <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Templates.xaml" />
            </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

这里真正的问题是,您的Window实际上不是Window:它是一个派生自Window的类,实际上是MainWindow,{{ 1}}等等......这意味着Window2的自动样式连接将从不以这种方式工作,并且遗憾的是总是需要一定程度的手动绑定。

答案 1 :(得分:2)

这是我在我的应用程序中使用的解决方案。它允许我将所有窗口样式保持在一起,并且在<Window.Resources>部分后只需要几行。

你的Style是这样的:

<Style x:Key="MyWindowStyle">
    <Setter Property="Window.Background" Value="AliceBlue"/>
</Style>

然后,在您的窗口中,在</Window.Resources>包括以下内容之后:

<Window.Style>
    <Style BasedOn="{StaticResource MyWindowStyle}"/>
</Window.Style>

答案 2 :(得分:-2)

在资源词典中添加新画笔

<SolidColorBrush x:Key="WindowBackground" Color="AliceBlue" />

并在WPF窗口中将所需资源设置为窗口背景属性

<Window x:Class="GDD.Presentation.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="300" Width="300"
    Background="{StaticResource WindowBackground}">