关于开发WPF的一些感想

简介:

开发的技术细节本文就不谈了,作者只想从感性上谈谈学习和实际开发WPF的感想。

      首先祝大家新年快乐,小生给大家拜个晚年!

      两年前暑假,从百度百科上第一次了解WPF,被它的强大特性所吸引,当然最让我着迷和期待的就是“绚丽”二字。两年来,放弃了曾经的Winform开发知识,全面转战WPF,开发了两三个大型项目,七八个游戏,和一些小型应用程序。也从当年的热烈走向现在的稳重。因此,愿意更从感性的角度讨论关于WPF的一些感想。

      本人只是在读研究生,且并非计算机科班出身,因此不足之处请海涵。

MVVM模式的思考

      以前开发winform程序,界面和程序是死死耦合在一起的,当修改了变量命名,改个样式,或者做了一些其他修改(那会还不知道resharper),不得不花费很长时间来“擦屁股”,因此深之界面和逻辑解耦的重要性。

      WPF很好的解决了这个问题,在设计之初就如此考虑,并引入了大名鼎鼎的MVVM模式。一开始不大了解,做得多了就懂了,一个ViewModel是不知道View的存在的,更利于分工合作,更利于单元测试。好处多得不得了。

     可是,凡是总有弊端,MVVM确实适应于大量数据的展示,修改等“业务逻辑”,通过数据和命令绑定,触发器等等的功能,可以很好的适应这种需求。可是,并非所有程序都是这种类型的,试想,开发一款简单的游戏,你需要控制时间线,动画效果,复杂样式还有数不清的其他需求。此时,你会发现,除了直接用ViewModel操作View,别无他法。当然,如果硬要做分离的话,也可以,附加行为(AttachBehavior)就是干这个的,通过静态依赖属性,写一个附加类来做这个,可惜,代码复杂度成倍增加,需要较高的学习成本,把简单问题搞复杂了。

     因此,我想说的是,MVVM是个好模式,可是别太追求完美,千万别捡了芝麻丢了西瓜,实在不行就耦合一下,这是一个很大的收获。

绑定到弱类型的xaml

      我和所有程序员一样,喜欢强类型的安全感。

      xaml绑定到了弱类型,好处在于更好的解耦,坏处在于没有了编译器和重命名工具的支持。我曾经用ReSharper修改变量名,从坐标名称”X“改成”PositionX“,于是,整个系统被这个重命名搞得一塌糊涂,让我修改了整整一天。运行时的绑定异常,比编译时更麻烦,好在有snoop.

      不过,这个没办法。慢慢适应吧。

到底是依赖属性还是INotifyCollectionChanged?

      常常需要在数据发生改变时通知界面(View)。于是便有了上面的问题。

      依赖属性真是个好东西,通过玩”静态“二字,玩得真是漂亮。博客园里有不少介绍依赖属性和附加属性的文章,此处就不引述了。它算是WPF的根基,动画,资源,绑定,无处不在的依赖属性。

      附加属性更是神奇,可以把属性记录在别的地方,”附加“这词用的很好。这让人想起了装饰器模式,动态增加属性和行为,只不过属性存储在了别的地方。

      既然依赖属性这么强大,我们干嘛还累死累活的让数据实现INotifyCollectionChanged接口?还写一堆麻烦的数据更新通知?比如如下恶心的代码:


private short _BreathRate; 
       public short BreathRate 
    { 
        get { return _BreathRate; } 
        set 
        { 
            if (_BreathRate != value) 
            { 
                _BreathRate = value; 
                OnPropertyChanged("BreathRate"); 
            }

        } 
    }

    这样的代码在WPF中无处不在,恶心死人。可是,如果用依赖属性的话,也会带来问题,有如下原因:

      1. 依赖属性的性能(肯定比原生的属性要慢)

      2. 依赖属性不能跨线程访问!包括读!这个问题在多线程情况下真是要命

      3. 必需继承于DependencyObject, 这不仅让你唯一的继承机会丧失,还引入了万恶的System.Windows命名空间,于是,你的未来代码移植会造成极大地困难。

      因此,我们有如下结论:

      算法和底层数据结构:毫无疑问,让它纯净一些,用INotifyCollectionChanged

      界面相关:包括自定义控件,自定义效果等等,放心的用依赖属性吧,绝对是正确选择。

     只有这样,界面逻辑解耦的愿望才能实现。

3D

       WPF号称支持3D,但我依旧要吐槽它,除了让人无法忍受的效率问题,开发工具,教学资料的匮乏,都让WPF的3D处于难以为继的状态。据我所知,仅有3DTools这些简单的WPF的3D扩展工具,以及一些很简单的辅助设计工具。用WPF开发3D,除非万不得已,否则我不会用它。在这一点上,WPF完全可以向Unity3D学习。

第三方类库

        WPF是个界面库,它天生就为良好的扩展性做好了准备。虽然不算多,但大部分需要的类库都有了,Avalondock, WPFToolkit, 物理引擎库,等等不一一列举了。这些库都比较新,不过很难看到WPF设计的完整软件作品,起码在国内看不到,他们都哪里去了???

性能

       程序性能问题,是任何程序员都非常关心的。WPF的性能疑问,来自两个方面,一个是动画,一个是数据更新造成的UI更新。

       我开发了几个游戏,发现比较复杂的物体移动,总会出现卡顿,那种令人不爽的“虚”感。使用更快的CPU和独立显卡可以较好的解决这个问题,可是在3317U这样的超级本平台上,程序运行起来风扇哄哄响,占用率达到一半。远远达不到unity3d这类3D平台上的性能和质量。同样效果的flash动画,也没有这种卡顿。这到底是怎么回事?

       在数据绑定上,我曾经懒惰的通过OnPropertyChanged(“”)的方式更新全部数据,但造成了严重的性能问题,因此建议仅更新对应的数据。

设计和美学

      这是个复杂的问题,有专门的学科研究,本部分仅浅尝辄止。

      我的经验,WPF在2D层面不限制你的任何想象力。但我有如下建议:对于一般软件而言,避免不必要的花哨,提供统一直观的UI效果是非常重要的,动画等技术的存在,仅在于表达数据和信息本身,若造成用户干扰,则有”炫技“嫌疑的东西可完全不要。Expression Design套件的设计对我们有很好的借鉴,黑色底色,淡灰色的文字,让你专注于设计本身,而非工具。我们应该专注如何让用户更好的关注数据。

     对于游戏或播放器等娱乐音乐而言,则设计思路有所不同。可以适当加入动画,在配色等角度可以更活泼,但一定注意整体设计的协调,与主题的搭配程度非常重要。

     设计是个复杂的事情,没事可以逛逛很多平面设计论坛,都有很大的收获。

前景?

      打个疑问号,表示该问题值得讨论。我没有真正深入业界,因此本节仅供参考。

      06年WPF技术公开,在08-09年貌似达到高峰。据我所知,博客园的绝大多数关于WPF的文章都是这个时期发布的,Blend等工具的出现,大大改进了界面设计方便性。但貌似,我这个软件控也没有看到除了微软这套Studio之外的,任何以WPF开发的商业软件系统。360,QQ,各类音乐播放器等等都没有,只有QQ概念版基于WPF,可是之后也没有更新了。究其原因,大概是需要安装.NET 3.5甚至4.0以上版本,部署起来不甚方便。也与当前程序普遍WEB化不无关系,

       但我依旧疑问,为什么在2010年之后,博客园很少有系统的WPF开发文章了?为什么到现在都没有客户端的WPF系统?它的前景究竟如何?

       不过,学WPF一点都不亏,xaml,数据绑定,和AE,PR类似的时间线系统,和绝高的开发效率,这些知识可以很快的转移到其他相关领域。

结语

       说了这么多,没用图片,也没拷贝大段代码,就是简单的聊聊。只是,在如今WEB化和移动化大行其道的情况下,windows桌面程序开发的价值又有几何?这难以估量,不过作为程序员,学习它,一点都不亏。

       本文的任何见解, 欢迎大家讨论。


相关文章
|
24天前
|
SQL 中间件 C#
一个使用 WPF 开发的管理系统
一个使用 WPF 开发的管理系统
|
24天前
|
网络协议 网络安全 C#
基于 WPF 开发的简约,功能强大的终端模拟器
基于 WPF 开发的简约,功能强大的终端模拟器 前言今天大姚给大家推荐一款基于 WPF 开发的简约,功能强大的终端模拟器:ModengTerm。项目介绍ModengTerm是一款基于 WPF 开发的简约,功能强大的终端模拟器,可以用来连接SSH服务器,串口,TCP服务器,Windows命令行等。项目功能支持与SSH服务器,串口,Windows命令行进行交互。可以保存会话信息,方便下次直接登录。支持将终端内容导出为txt和html格式。根据关键字/正则表达式进行历史记录的查找。同步输入功能、历史记录、度可定制化的颜色主题、实时记录日志功能等。项目源码运行设置ModengTerm为启动项目运行:
|
4月前
|
C# 开发者 Windows
WPF 应用程序开发:一分钟入门
本文介绍 Windows Presentation Foundation (WPF),这是一种用于构建高质量、可缩放的 Windows 桌面应用程序的框架,支持 XAML 语言,方便 UI 设计与逻辑分离。文章涵盖 WPF 基础概念、代码示例,并深入探讨常见问题及解决方案,包括数据绑定、控件样式与模板、布局管理等方面,帮助开发者高效掌握 WPF 开发技巧。
188 65
|
5月前
|
容器 C# Docker
WPF与容器技术的碰撞:手把手教你Docker化WPF应用,实现跨环境一致性的开发与部署
【8月更文挑战第31天】容器技术简化了软件开发、测试和部署流程,尤其对Windows Presentation Foundation(WPF)应用程序而言,利用Docker能显著提升其可移植性和可维护性。本文通过具体示例代码,详细介绍了如何将WPF应用Docker化的过程,包括创建Dockerfile及构建和运行Docker镜像的步骤。借助容器技术,WPF应用能在任何支持Docker的环境下一致运行,极大地提升了开发效率和部署灵活性。
211 1
|
5月前
|
测试技术 C# 开发者
“代码守护者:详解WPF开发中的单元测试策略与实践——从选择测试框架到编写模拟对象,全方位保障你的应用程序质量”
【8月更文挑战第31天】单元测试是确保软件质量的关键实践,尤其在复杂的WPF应用中更为重要。通过为每个小模块编写独立测试用例,可以验证代码的功能正确性并在早期发现错误。本文将介绍如何在WPF项目中引入单元测试,并通过具体示例演示其实施过程。首先选择合适的测试框架如NUnit或xUnit.net,并利用Moq模拟框架隔离外部依赖。接着,通过一个简单的WPF应用程序示例,展示如何模拟`IUserRepository`接口并验证`MainViewModel`加载用户数据的正确性。这有助于确保代码质量和未来的重构与扩展。
154 0
|
5月前
|
前端开发 C# 设计模式
“深度剖析WPF开发中的设计模式应用:以MVVM为核心,手把手教你重构代码结构,实现软件工程的最佳实践与高效协作”
【8月更文挑战第31天】设计模式是在软件工程中解决常见问题的成熟方案。在WPF开发中,合理应用如MVC、MVVM及工厂模式等能显著提升代码质量和可维护性。本文通过具体案例,详细解析了这些模式的实际应用,特别是MVVM模式如何通过分离UI逻辑与业务逻辑,实现视图与模型的松耦合,从而优化代码结构并提高开发效率。通过示例代码展示了从模型定义、视图模型管理到视图展示的全过程,帮助读者更好地理解并应用这些模式。
144 0
|
5月前
|
区块链 C# 存储
链动未来:WPF与区块链的创新融合——从智能合约到去中心化应用,全方位解析开发安全可靠DApp的最佳路径
【8月更文挑战第31天】本文以问答形式详细介绍了区块链技术的特点及其在Windows Presentation Foundation(WPF)中的集成方法。通过示例代码展示了如何选择合适的区块链平台、创建智能合约,并在WPF应用中与其交互,实现安全可靠的消息存储和检索功能。希望这能为WPF开发者提供区块链技术应用的参考与灵感。
77 0
|
5月前
|
开发者 C# Windows
WPF与游戏开发:当桌面应用遇见游戏梦想——利用Windows Presentation Foundation打造属于你的2D游戏世界,从环境搭建到代码实践全面解析新兴开发路径
【8月更文挑战第31天】随着游戏开发技术的进步,WPF作为.NET Framework的一部分,凭借其图形渲染能力和灵活的UI设计,成为桌面游戏开发的新选择。本文通过技术综述和示例代码,介绍如何利用WPF进行游戏开发。首先确保安装最新版Visual Studio并创建WPF项目。接着,通过XAML设计游戏界面,并在C#中实现游戏逻辑,如玩家控制和障碍物碰撞检测。示例展示了创建基本2D游戏的过程,包括角色移动和碰撞处理。通过本文,WPF开发者可更好地理解并应用游戏开发技术,创造吸引人的桌面游戏。
276 0
|
5月前
|
开发者 C# 自然语言处理
WPF开发者必读:掌握多语言应用程序开发秘籍,带你玩转WPF国际化支持!
【8月更文挑战第31天】随着全球化的加速,开发多语言应用程序成为趋势。WPF作为一种强大的图形界面技术,提供了优秀的国际化支持,包括资源文件存储、本地化处理及用户界面元素本地化。本文将介绍WPF国际化的实现方法,通过示例代码展示如何创建和绑定资源文件,并设置应用程序语言环境,帮助开发者轻松实现多语言应用开发,满足不同地区用户的需求。
106 0
|
5月前
|
开发者 C# UED
WPF多窗口应用程序开发秘籍:掌握窗口创建、通信与管理技巧,轻松实现高效多窗口协作!
【8月更文挑战第31天】在WPF应用开发中,多窗口设计能显著提升用户体验与工作效率。本文详述了创建新窗口的多种方法,包括直接实例化`Window`类、利用`Application.Current.MainWindow`及自定义方法。针对窗口间通信,介绍了`Messenger`类、`DataContext`共享及`Application`类的应用。此外,还探讨了布局控件与窗口管理技术,如`StackPanel`与`DockPanel`的使用,并提供了示例代码展示如何结合`Messenger`类实现窗口间的消息传递。总结了多窗口应用的设计要点,为开发者提供了实用指南。
348 0