自定义控件不继承父级的样式

p0l*_*ear 5 wpf xaml custom-controls .net-4.0

我试图在我的 WPF 应用程序中跨元素保持统一的外观和感觉,同时我想创建一个修改后的TextBox. 但是,当我这样做时,我在应用程序级别定义的样式TextBox不会应用于我创建的类,即使为我的自定义控件创建的样式正在使用该BasedOn属性。

是不是我遗漏了什么导致它的行为与我预期的不同?

我使用以下设置在 VS2010 中的一个全新 WPF 项目中重现了该问题:

C# 代码:

public class CustomTextBox : TextBox
{
    static CustomTextBox() {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomTextBox), new FrameworkPropertyMetadata(typeof(CustomTextBox)));
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML 中Themes\Generic.xaml:

<Style TargetType="{x:Type local:CustomTextBox}" BasedOn="{StaticResource {x:Type TextBox}}"/>
Run Code Online (Sandbox Code Playgroud)

XAML 中App.xaml:

<Application.Resources>
    <Style TargetType="TextBox">
        <Setter Property="Background" Value="Red"/>
    </Style>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

但是,在设计器中,当我运行应用程序时CustomTextBox,即使该BasedOn属性的文档表明我的派生类应该具有这种样式,但仍使用文本框的默认样式而不是红色背景...

可以通过多种方式扩展或继承 WPF 中的样式。样式可以通过此属性基于其他样式。使用此属性时,新样式将继承未在新样式中明确重新定义的原始样式的值。

...

注意:如果您创建具有 TargetType 属性的样式并基于另一个同样定义 TargetType 属性的样式,则派生样式的目标类型必须与基样式的类型相同或派生自基样式的类型。

小智 2

简短回答:您的样式基于 StaticResource

<Style TargetType="{x:Type local:CustomTextBox}" BasedOn="{StaticResource {x:Type TextBox}}"/>
Run Code Online (Sandbox Code Playgroud)

当你这样做时,你并没有改变 StaticResource

<Style TargetType="TextBox">
    <Setter Property="Background" Value="Red"/>
</Style>
Run Code Online (Sandbox Code Playgroud)

所以 CustomTextBox 不应该继承红色背景。