无法在generic.xaml中覆盖wpf控件的默认样式。
无法在generic.xaml中覆盖wpf控件的默认样式。
我们正在尝试通过更改generic.xaml中的默认样式来重新定义一些库存WPF控件。
通常情况下,我们会对控件进行子类化,并在其静态初始化器中覆盖子类化控件的默认样式键。然而,我们现在正试图直接覆盖基本控件,而不进行子类化。这样,公司中使用库存WPF控件的任何人都将默认获得我们的新样式。
但我似乎无法让它起作用。
在我的沙盒应用程序中,这是我们实际问题的简化版本,我有以下内容。
MainWindow.xaml
Themes/Generic.xaml
CustomTextBlock.cs
public class CustomTextBlock : TextBlock
{
static CustomTextBlock()
{
Type _CustomTextBlock = typeof(CustomTextBlock);
DefaultStyleKeyProperty.OverrideMetadata(
_CustomTextBlock,
new FrameworkPropertyMetadata(_CustomTextBlock));
}
}
结果如下图所示。
我的理论是,WPF引擎忽略了我们的样式,因为默认样式键要么未覆盖,要么在generic.xaml中首先找到了它们的样式。
我的问题是,有没有解决这个问题的方法?我的假设是否正确?
更新:
根据参考源代码,在TextBlock.cs文件的TextBlock类中,库存WPF控件已覆盖了默认样式键。
问题出现的原因是WPF在Themes文件夹中寻找默认样式时,会在与控件相同的程序集中查找。而你的控件是在你的程序集中定义的,而TextBlock是在PresentationFramework中定义的。因此,你最好为重定义标准控件创建另一个ResourceDictionary,并在每个xaml文档中包含/合并它。
解决方法是创建一个新的ResourceDictionary,并在其中定义对TextBlock的默认样式。然后,在你的应用程序中的每个xaml文件中,都包含/合并这个ResourceDictionary。
下面是一个示例,演示如何在Generic.xaml中重定义TextBlock的默认样式:
然后,在你的应用程序中的每个xaml文件中,使用MergedDictionaries将这个ResourceDictionary包含/合并进来:
这样,你就可以重定义TextBlock的默认样式,并将其应用到你的应用程序中的每个xaml文件中了。
无法重写wpf控件的默认样式的原因是在generic.xaml文件中,wpf控件的默认样式被硬编码为静态资源。因此,无法通过在App.xaml中定义具有相同键的样式来覆盖默认样式。
解决方法是将自定义样式放在DefaultStyles.xaml文件中,并将其添加到App.xaml的MergedDictionaries中。如果DefaultStyles.xaml文件在Themes文件夹中,可以使用以下代码将其添加到MergedDictionaries中:
如果DefaultStyles.xaml文件在另一个程序集中,可以使用以下代码将其添加到MergedDictionaries中:
需要注意的是,`DefaultStyles.xaml`的名称可以是任何名称,上述示例仅为示例。