专栏首页dino.c的专栏[WPF]何如在Win7使用Aero2主题

[WPF]何如在Win7使用Aero2主题

1. 问题

假设我在Windows10的环境新建一个4.6的WPF项目,添加一个ComboBox,并用Blend在这个ComboBox上右键“编辑模板”->“编辑副本”,Blend不仅帮我创建了模板,还会自动引用PresentationFramework.Aero2这个DLL,即使用Aero2这个主题的资源文件。一切看起来很简单,直接,纯真,善良,但将这个项目放到Windows7环境下运行就会报这样的错误:

“System.IO.FileNotFoundException: 未能加载文件或程序集“PresentationFramework.Aero2, PublicKeyToken=31bf3856ad364e35”或它的某一个依赖项。系统找不到指定的文件。”

既没做什么丧尽天良的事,也没做什么泯灭人性的操作,然而程序出错了。

2. 原因

先来说说什么是Aero2。

WPF提供了以下几种主题

主题文件

桌面主题

Classic.xaml

Windows XP 操作系统上的经典 Windows 外观(Windows 95、Windows 98 和 Windows 2000)。

Luna.NormalColor.xaml

Windows XP 上的默认蓝色主题。

Luna.Homestead.xaml

Windows XP 上的橄榄色主题。

Luna.Metallic.xaml

Windows XP 上的银色主题。

Royale.NormalColor.xaml

Windows XP Media Center Edition 操作系统上的默认主题。

Aero.NormalColor.xaml

Windows Vista 操作系统上的默认主题。

Windows 8 之后WPF更新了Aero2和AeroLite两种主题,关于Aero、Aero2、AeroLite的区别具体可见这个网页。再之后微软就没有更新WPF主题了

Aero

Aero2

WPF程序启动时大概就是用这段代码确定主题,也就是说默认是Aero,如果在Windows 8 或以上自动转为Aero2:

_themeName = themeName.ToString();
_themeName = Path.GetFileNameWithoutExtension(_themeName);

if(String.Compare(_themeName, "aero", StringComparison.OrdinalIgnoreCase) == 0 && Utilities.IsOSWindows8OrNewer)
{
    _themeName = "Aero2";
}

所以在Windows 10上使用Blend获取控件模板的副本时Blend识别出当前使用Aero2的主题并主动引用了Aero2相关的资源。

那么为什么在WIndows 7 中使用Aero2会出错呢?用Bing搜一搜答案就出来了:

Problem with assembly PresentationFramework.Aero2

The assembly PresentationFramework.Aero2 in your project is metadata only assembly, which is used in dev time. You can get the full assembly under: C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF Please try to replace with the correct assembly. It should work.

简单来说就是在C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.6\PresentationFramework.Aero2.dll这个位置的是个假货(大小为161K)。真货在C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF这个目录下(大小为248K),但WIN7下同个目录找不到Aero2这个DLL。

3. 解决方案

知道问题原因后,要解决这个问题就很简单了,随随便便都能想到3个:

  1. 在Windows10电脑上找到C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.Aero2.dll这个DLL,放到项目中,并在项目中引用这个DLL。
  2. 在Nuget上搜搜Aero2,找个上去像那么回事的,例如这个
  3. 用ILSpy反编译Aero2.dll,把需要的样式复制粘贴到自己的项目中。

简单测试了看上去都没问题,不过,其实,可是我都没有用这三个方案。

4. 实际上根本不需要Aero2?

回到最开始的问题,ComboBox的样式用到Aero2的地方只有Themes:SystemDropShadowChrome这个部分,这用于给弹出菜单提供阴影。而这个类在Aero(不是2)中也有提供,在我记忆里两个DLL中这个类的实现完全一致,将Aero2的引用替换成Aero就可以解决这个问题了。甚至反编译后获取SystemDropShadowChrome的源码自己创建一个也可以。

5. 结语

程序员的开发环境总是用最新的,但客户环境不受控制,最近还听到人抱怨要兼容XP的电脑。我以前面对的客户群体都比较单一所以没有太多兼容性方面的经验,所以这次才踩了这么明显的坑,不知道有没有这方面的完整的指南?

6. 参考

Problem with assembly PresentationFramework.Aero2 Getting Started PresentationTheme Aero

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2fe5qd7iobmso

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • [WPF]何如在Win7使用Aero2主题

    假设我在Windows10的环境新建一个4.6的WPF项目,添加一个ComboBox,并用Blend在这个ComboBox上右键“编辑模板”->“编辑副本”,B...

    dino.c
  • [UWP]在应用退出时弹出确认提示框

    在应用退出时(点击右上角的关闭按钮)弹出一个确认按钮可以说是一个最常见的操作了,例如记事本的“你是否保存”:

    dino.c
  • [UWP 自定义控件]了解模板化控件(5.1):TemplatePart vs. VisualState

    在前面两篇文章中分别使用了TemplatePart及VisualState的方式实现了相同的功能,其中明显VisualState的方式更灵活一些。如果遇到这种情...

    dino.c
  • [WPF]何如在Win7使用Aero2主题

    假设我在Windows10的环境新建一个4.6的WPF项目,添加一个ComboBox,并用Blend在这个ComboBox上右键“编辑模板”->“编辑副本”,B...

    dino.c
  • MySQL入门详解(二)---mysql事务、锁、以及优化

    1.脏读:事务A读取了事务B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据

    步履不停凡
  • JVM笔记-前端编译与优化

    所谓”编译“,通俗来讲就是把我们写的代码“翻译“成机器可以读懂的机器码。而编译器就是做这个翻译工作的。

    WriteOnRead
  • 原来《庆余年》里的范闲是这样成为人生赢家的!

    小N中午在公司食堂吃饭,偷瞄了一眼拼桌的其余三位同事地屏幕,竟然都在看《庆余年》!零宣传上线,开播二十余天,这部豆瓣8.0高分的电视剧,刷爆了最近的朋友圈。 ...

    腾讯NEXT学位
  • 使用ELK实时分析SSH暴力破解

    在上一篇《通过rsyslog搭建集中日志服务器》,我们分享了如何通过rsyslog搭建集中日志服务器,收集系统日志,在本篇,我们会利用这些系统日志进行安全分析。

    Bypass
  • ONOS编程系列(一)之简单应用开发

    一个ONOS application是使用maven做管理的OSGi bundle。 因此,ONOS application 可以归结为Java类和POM文件的...

    SDNLAB
  • 浅析PropertySource 基本使用

    一、PropertySource 简介二、@PropertySource与Environment读取配置文件三、@PropertySource与@Value读取...

    cxuan

扫码关注云+社区

领取腾讯云代金券