WPF覆盖合并字典中的样式

Ste*_*eve 3 c# wpf resourcedictionary

在我的词典文件中

<Style TargetType="{x:Type Label}" BasedOn="{StaticResource {x:Type Label}}">
    <Setter Property="Foreground" Value="White" />
    <Setter Property="Background" Value="Black" />
</Style>
Run Code Online (Sandbox Code Playgroud)

在我的Window xaml文件中,我有

    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/XXX;component/XXX.xaml"/>
            </ResourceDictionary.MergedDictionaries>

            <Style TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
                <Setter Property="FontSize" Value="20"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
            </Style>
        </ResourceDictionary>
    </Window.Resources>
Run Code Online (Sandbox Code Playgroud)

在设计师中我可以看到标签有黑色背景和白色前景,但在运行时它有默认的黑色前景和透明背景.很明显,我想继承字典样式,但它不起作用.我在那里做错了什么?我正在使用VS 2013和.NET 4.5

编辑:如果我删除Windows.Resources中的样式,那么将应用字典样式.如果我将样式从Windows资源移动到包含一些标签的StackPanel.Resource,那么继承可以正常工作

Pie*_*oet 5

根据MSDN,Merged Resource Dictionaries:

If a key is defined in the primary dictionary and also in a dictionary that was merged, then the resource that is returned will come from the primary dictionary.

根据这条规则,首先找到你的第二种风格.然后,该样式引用具有相同{x:Type Label}键的样式.由于某种原因,这解决了null.然而,检查第一个样式表明其BasedOn引用已按预期解析为默认的Label样式.当两个样式都被赋予相同的显式键时,会发生同样的情况.然而,当给予不同的键时,一切都按预期工作.

我的猜测是第二种风格影响第一种风格.也许BasedOn引用被解析为样式本身,但为了防止循环依赖,它被设置为null.

我个人会使用显式键.对于需要应用于某种类型的所有元素但在某些情况下仍需要重写的样式,我会将其分为两种样式:

// The actual style, with all its setters, is given a descriptive name:
<Style x:Key="DescriptiveName" TargetType="Label" BasedOn="{StaticResource {x:Type Label}}">
    // Setters go here
</Style>

// A 'dummy' style that references the above style.
// Its sole purpose is to apply the style to all elements of the target type.
<Style TargetType="Label" BasedOn="{StaticResource DescriptiveName}" />
Run Code Online (Sandbox Code Playgroud)

当您需要覆盖样式时,可以通过它的名称明确地引用它:

<Style TargetType="Label" BasedOn="{StaticResource DescriptiveName}">
    // Overriding setters go here
</Style>
Run Code Online (Sandbox Code Playgroud)

  • 那么字典是一个全球风格的字典。如果我不想覆盖任何内容,我试图避免必须执行 style = {...} 或必须在字典中创建另一个 Style 。 (2认同)