通过Themes/Generic.xaml为WPF控件提供默认样式不生效

1. 我有一个netframework4.8的类库项目,里面提供了一个自定义控件,然后我按照以下方法为控件提供了默认样式

  a) 添加Themes\Generic.xaml文件,文件中提供自定义控件的默认样式

<Style TargetType="MyControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="MyControl">
                //.......
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

 

  b) 在自定义控件的静态构造函数中,添加

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), new FrameworkPropertyMetadata(typeof(MyControl)));

  现在一切正常,Generic.xaml中定义的默认样式能够自动应用到我的自定义控件上

2. 后面我想把项目升级成net8.0,因为旧的代码是半成品并且代码很少,我就没有在旧项目上升级,而是直接新建了一个net8.0的类库项目,然后将关键代码拷贝了过去,结果默认样式不生效了。

3. 经过排查发现,原来是我在创建net8.0的项目时,误选择了“类库”模板而非“WPF用户控件库”模板,“WPF用户控件库”模板相对于“类库”模板,项目下多了一个AssemblyInfo.cs文件,内容如下

using System.Windows;

[assembly:ThemeInfo( ResourceDictionaryLocation.None,
//主题特定资源词典所处位置 //(未在页面中找到资源时使用, //或应用程序资源字典中找到时使用) ResourceDictionaryLocation.SourceAssembly //常规资源词典所处位置 //(未在页面中找到资源时使用, //、应用程序或任何主题专用资源字典中找到时使用) )]

正是ThemeInfo特性指定了资源文件的位置。

ThemeInfoAttribute的构造函数有两个参数,分别表示特定于主题的资源文件的路径和非特定于主题的资源文件的路径。ResourceDictionaryLocation是一个枚举类型,当值等于SourceAssembly时,资源文件应放在Themes\目录下

public ThemeInfoAttribute(System.Windows.ResourceDictionaryLocation themeDictionaryLocation, System.Windows.ResourceDictionaryLocation genericDictionaryLocation);

4. 最后解决方案有两个:

  a) 在项目下创建AssemblyInfo.cs文件,为程序集提供ThemeInfo特性

  b) (推荐)通过项目文件提供ThemeInfo特性,在csproject项目文件中添加以下代码

<Project Sdk="Microsoft.NET.Sdk">

  ........

  <ItemGroup>
    <AssemblyAttribute Include="System.Windows.ThemeInfoAttribute">
      <_Parameter1>System.Windows.ResourceDictionaryLocation.None</_Parameter1>
      <_Parameter1_TypeName>true</_Parameter1_TypeName>
      <_Parameter2>System.Windows.ResourceDictionaryLocation.SourceAssembly</_Parameter2>
      <_Parameter2_IsLiteral>true</_Parameter2_IsLiteral>
    </AssemblyAttribute>
  </ItemGroup>

</Project>

 

来源链接:https://www.cnblogs.com/yangtb/p/18860425

© 版权声明
THE END
支持一下吧
点赞12 分享
评论 抢沙发
头像
请文明发言!
提交
头像

昵称

取消
昵称表情代码快捷回复

    暂无评论内容