zoukankan      html  css  js  c++  java
  • [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:WindowsMicrosoft.NETFrameworkv4.0.30319WPF
    Please try to replace with the correct assembly. It should work.

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

    3. 解决方案

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

    1. 在Windows10电脑上找到C:WindowsMicrosoft.NETFrameworkv4.0.30319WPFPresentationFramework.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

  • 相关阅读:
    x-www-form-urlencoded与multipart/form-data区别
    objc_msgSend method_getTypeEncoding 与 @encode
    历史文件备份,原文件已损失
    和安全有关的那些事(非对称加密、数字摘要、数字签名、数字证书、SSL、HTTPS及其他)
    HTTP权威指南 目录
    Makefile 与tab
    NSString+URLParser NSScanner
    (转)虚拟文件系统(VFS)浅析
    Linux套接字与虚拟文件系统(1):初始化和创建
    linux内核中的文件描述符(二)--socket和文件描述符
  • 原文地址:https://www.cnblogs.com/dino623/p/Windows7-Using-Aero2.html
Copyright © 2011-2022 走看看