默认样式不适用于子类

soh*_*hum 2 c# wpf xaml

我有一个奇怪的场景涉及覆盖WPF中的默认样式并将它们应用于子类.这不可能吗?例如,我有以下代码:

<Window x:Class="TestWPFStyling.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:testWpfStyling="clr-namespace:TestWPFStyling"
        Title="MainWindow" Height="350" Width="525" Background="White">
    <Window.Resources>
        <Style TargetType="testWpfStyling:SomeLabel">
            <Setter Property="Foreground" Value="Red" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <testWpfStyling:SomeLabel Grid.Row="0">This should be red.</testWpfStyling:SomeLabel>
        <testWpfStyling:YellowLabel Grid.Row="1">This should be red.</testWpfStyling:YellowLabel>
        <StackPanel Grid.Row="2">
            <StackPanel.Resources>
                <Style TargetType="testWpfStyling:SomeLabel">
                    <Setter Property="Foreground" Value="Blue" />
                </Style>
            </StackPanel.Resources>
            <testWpfStyling:SomeLabel>This should be blue.</testWpfStyling:SomeLabel>
            <testWpfStyling:YellowLabel>This should be blue.</testWpfStyling:YellowLabel>
        </StackPanel>

    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

有了这个代码隐藏:

namespace TestWPFStyling
{
    public partial class MainWindow : Window
    {
    }

    public class SomeLabel : Label
    {
    }

    public class YellowLabel : SomeLabel
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

我希望StackPanel中的控件YellowLabel颜色为蓝色,外部颜色为红色,但两者都是黑色.子类是否有办法采用其父类的默认样式?

小智 8

实际上这就是WPF的工作原理.我有一篇博客文章讨论了WPF样式(主要是关于我们的Theme属性如何工作),但问题1的场景1的基本问题与您所描述的相同.也就是说,使用实际的类类型定位隐式本地样式,并且与DefaultStyleKey无关.DefaultStyleKey仅在查找默认样式时使用(即,基于当前OS主题应用于控件的样式和控件的默认generic.xaml).解决此问题的一种简单方法是将派生控件的样式(例如,在其ctor中)设置为对基类样式的DynamicResource引用.例如

this.SetResourceReference(StyleProperty, typeof(SomeLabel));
Run Code Online (Sandbox Code Playgroud)