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

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

1. 问题

假设我在Windows10的环境新建一个4.6的WPF项目,添加一个ComboBox,并用Blend在这个ComboBox上右键“编辑模板”->“编辑副本”,Blend不仅帮我创建了模板,还会自动引用<code>PresentationFramework.Aero2</code>这个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.

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

3. 解决方案

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

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

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

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

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

5. 结语

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

6. 参考

Problem with assembly PresentationFramework.Aero2

Getting Started PresentationTheme Aero

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

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

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

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

    dino.c
  • [.NET]使用十年股价对比各种序列化技术

    上一家公司有搞股票,当时很任性地直接从服务器读取一个股票10年份的股价(还有各种指标)在客户端的图表上显示,而且因为是桌面客户端,传输的数据也是简单粗暴地使用S...

    dino.c
  • [UWP]用画中画模式(CompactOverlay Mode)让用总在最前端显示

    Windows 10 Creators Update以后UWP提供了一个新的视图模式CompactOverlay,中文翻译成 紧凑的覆盖层?反正大部分时间我们都...

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

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

    dino.c
  • Gank Alfred Workflow

    下载最新版本的workflow文件双击使用Alfred打开即可,workflow也已提交到Packal。

    宅男潇涧
  • 设计模式的六大原则

    单一职责原则: 定义:不要存在多于一个导致类变更的原因。 通俗地说:一个类只负责一项职责。 问题来源:一个类T负责两个职责:职责1和职责2,当因为职责1因需求变...

    用户1134788
  • Spring事务事件监控

    本文首先会使用实例进行讲解Spring事务事件是如何使用的,然后会讲解这种使用方式的实现原理。

    JavaQ
  • 分析Spring是如何做事务事件监控的

    无论是事务开始,提交或者回滚,都会触发相应的事务事件。本文首先会使用实例进行讲解Spring事务事件是如何使用的,然后会讲解这种使用方式的实现原理。

    用户4143945
  • 如何将win10家庭版升级到win10专业版

    家庭版系统是绝大多数新电脑厂商出厂默认的系统,很多功能都无法使用,有些软件也不支持家庭版本,那么如何将家庭版系统升级为专业版呢,接下就给大家说下步骤,

    用户5459522
  • MyBatis的9种设计模式,我猜你不知道

    虽然我们都知道有26个设计模式,但是大多停留在概念层面,真实开发中很少遇到,Mybatis源码中使用了大量的设计模式,阅读源码并观察设计模式在其中的应用,能够更...

    挨踢小子部落阁

扫码关注云+社区

领取腾讯云代金券