来自generic.xaml的样式不适用

Seb*_*ERT 18 wpf themes styles generic.xaml

我创建了一个类库程序集,我在其中创建了自定义控件,并在generic.xaml文件中定义了默认样式.

这似乎是一个相当普遍的问题,只要有很多人发布它.但是我找不到任何有用的答案.

  • generic.xaml位于Themes文件夹中.
  • generix.xaml文件Build Action设置为Page.
  • ThemeInfo在我的AssemblyInfo.cs中正确定义.

在我的测试应用程序中,如果我手动将我的自定义控件程序集中的generic.xaml文件合并到应用程序App.xaml文件中,如下所示:

<Application.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <ResourceDictionary Source="/MyControlsAssembly;component/Themes/generic.xaml"/>
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</Application.Resources>
Run Code Online (Sandbox Code Playgroud)

然后自定义控件正确主题,但如果我不手动合并generic.xaml,控件将显示默认的Windows主题.

你能告诉我我忘记和/或做错了什么吗?

附加信息:

  • 我的ThemeInfo程序集属性定义如下:

    [assembly: ThemeInfo(ResourceDictionaryLocation.SourceAssembly, ResourceDictionaryLocation.SourceAssembly)]

    (注意:结果与ThemeInfo属性的任何参数组合相同)

  • Themes文件夹中的generic.xaml文件旁边还有另外两个.xaml文件.

  • Themes文件夹中有一个子文件夹,它本身包含另一个.xaml文件.

Ete*_*l21 11

您需要在自定义控件构造函数中使用以下行:

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

然后,如果在themes文件夹中有generic.xaml文件,则使用以下示例样式:

<Style TargetType="{x:Type local:MyCustomControl}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MyCustomControl}">
                <Border>
                    <Label>Testing...</Label>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)

现在风格将自动应用,无需任何额外的合并.


小智 9

为了在我的自定义控件库中的Themes\Generic.xaml中应用默认样式,我决定从一个成熟的开源控件库(MahApps)中寻找灵感.这个项目为您提供了一个如何构建和布局自定义控件库的非常好的示例.

简而言之,要在Themes\Generic.xaml中获取默认样式,您需要在自定义控件库的AssemblyInfo.cs文件中包含以下内容:

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
Run Code Online (Sandbox Code Playgroud)

在我的例子中,我的自定义控件AssemblyInfo.cs看起来像:

using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Markup;

[assembly: AssemblyCopyright("...")]
[assembly: ComVisible(false)]

[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyTitleAttribute("...")]
[assembly: AssemblyDescriptionAttribute("")]
[assembly: AssemblyProductAttribute("...")]
[assembly: AssemblyCompany("...")]
Run Code Online (Sandbox Code Playgroud)