C# 样式:BasedOn和DefaultStyleKeyProperty.OverrideMetadata

C# 样式:BasedOn和DefaultStyleKeyProperty.OverrideMetadata,c#,wpf,styles,custom-controls,C#,Wpf,Styles,Custom Controls,在Visual Studio中创建自定义控件时,会自动添加静态构造函数: static MyListBoxItem() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MyListBoxItem), new FrameworkPropertyMetadata(typeof(MyListBoxItem))); } 风格 <Style TargetType="{x:Type c:MyListBoxItem}"> &l

在Visual Studio中创建自定义控件时,会自动添加静态构造函数:

static MyListBoxItem()
 {
     DefaultStyleKeyProperty.OverrideMetadata(typeof(MyListBoxItem), new FrameworkPropertyMetadata(typeof(MyListBoxItem)));
 }
风格

<Style TargetType="{x:Type c:MyListBoxItem}">
  <Style.Resources>
     <!--SelectedItem with focus-->
     <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Red" />
 </Style.Resources>
</Style>

然后给出一个空的布局。没有静态构造函数中的代码,布局是正确的。只要不将
覆盖默认样式
设置为true

当我向样式添加
BasedOn=“{StaticResource{x:Type ListBoxItem}}”
时,无论是否使用静态构造函数代码,布局都是正确的<代码>覆盖默认样式不再有效

我更希望自定义控件的样式默认为基类型的样式。 在我看来,静态构造函数中的代码似乎可以省略。
但为什么默认情况下会生成它?

来自第页:

控件通常会将此属性的默认值重写为其自己的类型,但在某些情况下,还可以使用主题词典中存在样式的基类型。只有当基本控件的控件模板完全定义了该派生控件的可视表示,并且派生类型公开的任何其他成员不需要作为控件模板一部分的其他元素时,这才是可行的

在您的情况下,您希望自定义控件在默认情况下使用基本控件样式。要实现这一点,您必须从静态构造函数中删除该行,或者用以下行替换它,以指示您要使用基本控件样式

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyListBoxItem), new FrameworkPropertyMetadata(typeof(ListBoxItem)));

我想,从静态构造函数中删除该行会更好。

如果您再次查看
DefaultStyleKeyProperty.OverrideMetadata
方法中的参数,您会发现没有提到
ListBoxItem
。。。代码的意思是,对于类型为
MyListBoxItem
的对象,您提供的
样式应该是默认的
样式?因此,我想知道为什么没有应用带有隐式类型键的样式。您是正确的,
StyleKey
实际上不是一个
Style
,但它与
Style
相关,或者是我所理解的
Style
的引用。这行代码仍然用于告诉
框架
generic.xaml
中查看控件的默认
样式
。我不知道为什么它不起作用。这是一个有趣的问题,但不幸的是,我目前无法测试您的场景。。。我稍后回家时会尝试。为了安全起见:我不使用
generic.xaml
-将其移动到另一个文件中。可能这就是为什么不应用您的
样式的原因。。。尝试将其移回
generic.xaml
文件。这是框架将为
CustomControl
s查找默认
Style
的文件。默认样式中没有OverrideMetadata和BasedOn也可以使用。