如何使自定义控件自动应用资源字典中定义的样式?

How can I make a Custom Control automatically apply a style defined in a resource dictionary?

我有一个带有自定义控件的控件库:

public class GlassButton : Button {
}

我还定义了一个资源字典来设置控件的样式:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:Animations="clr-namespace:WPFTools.Classes"
    xmlns:Controls="clr-namespace:WPFTools.Controls"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
    mc:Ignorable="d">
    <Style TargetType="{x:Type Controls:GlassButton}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">

我希望能够简单地将 GlassButton 拖放到 window 或控件上,而 NOT 必须这样做:

<Window.Resources>
    <ResourceDictionary Source="Foo"/>
</Window.Resources>

我以前做过一次,但我似乎已经忘记了这些知识。

我怎样才能做到这一点? (我很好地更改了我的控件背后的代码)。

我不得不重新记住一周前它是如何工作的,这就是我必须做的才能让它为我工作。使用自定义控件的典型方法是在项目根目录正下方的 Themes 文件夹中名为 generic.xaml 的文件中定义样式。然后你需要在自定义控件的静态构造函数中覆盖默认样式class。它看起来像这样:

public class GlassButton : Button
{
    static GlassButton()
    {
        DefaultStyleKeyProperty.OverrideMetadata( typeof( GlassButton ),
            new FrameworkPropertyMetadata( typeof( GlassButton ) ) );
    }
}

最后,您需要设置适当的程序集 属性 以表明您的通用主题位于您的程序集中。像这样的东西会进入你的 Properties\AssemblyInfo.cs 文件:

using System.Windows;
[assembly:ThemeInfo( ResourceDictionaryLocation.None,
    ResourceDictionaryLocation.SourceAssembly )]

我不确定这是否绝对必要,但在默认样式正确应用到我的文件之前,我还必须将 generic.xaml 文件上的构建操作 属性 更改为 Page控制。

这项工作的最佳实践是创建 DictionaryResources,其中包含应用程序中您想要的每种应用程序样式的所有 WPF 样式。

因此您可以删除当前样式并动态添加新样式,如下所示: