WPF四年,尤不足以替代WinForm

WPF出山已四年,作为官方内定的下一代UI系统掌门,没少露脸。但这个新掌门能否胜任,仍是众多开发者的心头之虑。通过对VisualStudio 2010的编辑器部分用WPF重写,微软终于对这个胜任与否的问题给出了个证实,当然,也给WPF做了不少重要的改进,尤其是终于解决了文本看不清的问题。所以,至少从.NET 4开始,WPF应该可以比较安全的用于重要的开发项目了。

但是,使用WPF并不会象用WinForm那样顺利。

首先,它太复杂了,入门门槛很高。这种复杂性一定程度上源于它统一桌面和Web开发的野心。用一套Framework来同时支持桌面和Web,固然很好,但也同时继承了两者的复杂性。如果既有WinForm又有ASP.NET开发经验的话,就会觉得这种合并很自然,有前途。当然,WPF还有更高的目标,就是挑战Flash。这种以一当三的精神固然可嘉,可以想象同时击败三派风格迥异的武林掌门的话会有多强大。但对我们学、用WPF的开发者而言,有多少人是要同时针对两个甚至三个领域的?即使只需面对其中一个领域,我们也得面对WPF的全部复杂度。当然,也有潜在的好处,可以轻松的引入另外两个领域的技术。

其次,对WinForm开发者而言,入门WPF可能还要更困难,因为最基本的东西——制作界面的XAML,完全是Web式的风格和思路。原来WinForm的知识和技能,大部分都不再适用。一开始就要面对的选择是Document、Window、Page、NavigationWindow等,而不是一个简单的Form。创建Window后,如果指望象WinForm那样设计窗体,就会发现它的窗口设计器基本是个笑话,还是老老实实地手写XAML吧,这时会庆幸自己还曾学过点HTML。如果无法忍受手写XAML,那么可以下载Expression Blend,类似于Flash编辑器,这时会庆幸自己还曾搞过那么点美工,会用Flash。

之后,会发现加个Tool Button竟然不能直接同时指定图标和文本,还必须嵌套一层StackPanel;Disable时图标不会变灰,需要自己写Style来实现;ToolBar末尾的Overflow popup按钮总是显示很讨厌,要隐藏就得在ControlTemplate上最手脚;DropDownButton也没有,要自己实现……不少WinForm里习以为常的东西,突然都没有了。虽然通过强大的Style系统和Composition都能实现,但毕竟是要费额外的功夫。

Resource的添加和管理比以前倒是简单了,只要把文件加入project里,自由组织目录结构,把文件的Build Action设置成Resource就行了。但是引用资源文件的路径就搞恶了,不知道是哪个精神异于常人的家伙发明了这个Pack URI的规则(形如pack://application:,,,/ReferencedAssembly;v1.0.0.1;component/MyResourcePath/ResourceFile.xaml),一看见我就想打沙包。所幸多数情况下只需要相对路径,可以省略前面那串欠扁的东西。

数据绑定算是编程模式上最大的改变之一了,与UI的数据交互几乎全部通过绑定来实现,简单的情况会很简单,很强大,比WinForm里的数据绑定强多了。但复杂的情况就让人挠头了。稍微复杂一点就必须写个ViewModel层,也就是要写个介于UI和业务逻辑之间的交互类,UI都绑定到这个类的属性上。之后要考虑的是数据显示的格式化问题,比如如何把一个浮点数显示成百分数输出;组合多个属性合并成一个输出的问题;还有用户输入的合法性校验问题;限制可输入字符的问题;想要在按回车键时接受处理输入的问题……这些都不是直接了当有现成支持的问题,需要自己写些代码来解决。

除此之外,WPF的语言本地化工具支持基本等价于零,只有复杂难用的命令行工具,还是SDK的sample编译的。要做本地化翻译基本只能靠第三方工具。

更有趣的是,WPF程序缺省使用en-US的Culture,而不管当前系统的Culture是什么,需要自己写代码在程序启动时设置Window或控件的Language属性,或者Override它的FrameElement.LanguageProperty的MetaData里的缺省值。当然,这个不是bug,而是by design。其原因来自最早.NET的一个设计错误。

当年最初设计.NET时,他们计划将全球化和本地化支持从基础库部分开始支持,以便使之适应未来越来越全球化的市场,于是所有的字符串格式化函数都是缺省使用当前系统culture的。但此时所有其他开发语言里,缺省都是en-US标准。结果,大量的程序并未考虑这种差异,其结果一是性能损失,考虑本地化的字符串处理的开销要比简单的二进制字符串处理慢很多,二是导致了大量在不同语言系统上会出现的bug。比如,在德文系统上生成个浮点数“1.23”文本,出来是“1,23”,发送到英文系统上读取,就解析出错了。再比如,不同语言的大小写对应是不同的,转换大小写在不同语言的系统上可能得到不同的结果,在文件名、路径处理上会导致意想不到的bug。开发.NET 2.0时,.NET的开发者们已经意识到了这个错误,但已经不能更改已有的API了,于是只能为这些函数增加了带新参数的重载,并推荐大家不要再用旧的API,而要用这些写起来非常长的函数,如string.Equals(string another, StringComparison comparisonType),用string.Format()时也最好用指定Culture的那个重载,充分利用CultureInfo.InvariantCulture。WPF的设计者们充分吸取了这个教训,所以缺省总是en-US,需要本地化的地方要显示指定。

再之外,ILMerge是不能正确合并WPF的assembly的,因为它不能修正baml里对资源的引用字符串。也就意味着,基于ILMerge的obfuscator也有这个问题。不过对Obfuscator而言,要支持WPF本身就不是件容易的事。因为WPF依赖与数据绑定,数据绑定里大量用对象属性的名字字符串,而编译之后XAML会被编译成二进制的BAML,而BAML的格式是非公开的。这样就不能去改被引用的对象属性名。

总而言之,WPF还有很多路要走,前途是光明的,道路是曲折的。未来是WPF的,也是WinForm的,但归根结底都是韩国人的?

http://blog.csdn.net/nightmare/article/details/5572556

WPF四年,尤不足以替代WinForm的更多相关文章

  1. WPF 四种尺寸单位

    原文:WPF 四种尺寸单位 像素 px 默认单位可以省略 厘米cm 英寸 in 点 pt 1in = 96px 1cm=96/2.42px 1pt=96/72px

  2. [WPF]建立自适应窗口大小布局的WinForm窗口

    编写WinForm程序时,都会碰到一个问题.就是WinForm窗口在不同分辨率下的大小问题.举例说明,你编写的WinForm窗口在1024×768下是合适.匀称的.不过,如果用户的计算机的分辨率为14 ...

  3. (四十二)c#Winform自定义控件-进度条扩展

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  4. (四十九)c#Winform自定义控件-下拉框(表格)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  5. (四十六)c#Winform自定义控件-水波进度条-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  6. (四十五)c#Winform自定义控件-水波图表

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  7. (四十八)c#Winform自定义控件-下拉按钮

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  8. 练手WPF(四)——贪吃蛇小游戏的简易实现(下)

    八.生成新的单节蛇身我们这里先说说游戏小原理好了,游戏运行后,通过计时器事件不断生成新的单节蛇身类SnakeNode,添加到List中的0位置,原来的蛇头变成了第二节.该节新蛇头的坐标通过蛇头前进方向 ...

  9. 练手WPF(四)——贪吃蛇小游戏的简易实现(上)

    一. 游戏界面首先,按照惯例,编辑MainWindow.xaml,先将游戏界面制作好.非常简单:(1)主游戏区依然使用我们熟悉的Canvas控件,大小为640X480像素,设定每小格子为20px,所以 ...

随机推荐

  1. python2.x脚本转换为python3.x脚本的方法

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/dushu990/article/details/73549174 python2.x脚本转换为pyt ...

  2. python列表分页

    列表分页   上章的结束,若在实际开发过程中,会发现一个问题,那就首页或关注分享,是一下子按时间顺序全部显示出来,这在实际项目中不可能出现的,想想实际中的产品是如何做的? 一般来说,无非是两种,一种是 ...

  3. Cordova 代码热更新 - 简书

    原文:Cordova 代码热更新 - 简书 Cordova 代码热更新 [图片上传失败...(image-a19be7-1521624289049)] 基于 Cordova 框架能将网页应用 (js, ...

  4. Java InputStream、String、File相互转化 --- good

    String --> InputStreamByteArrayInputStream stream = new ByteArrayInputStream(str.getBytes()); Inp ...

  5. 数学概念 —— 奇异性(Singularity,Vertical tangent)

    0. 基本定义 Singularity (mathematics) 数学上的奇异性一般是指,函数在该点未定义(not defined,比如取值为无穷),或者不可微(fails to be well-b ...

  6. 解决android模拟器无法上网问题

    1.  将 android的tool增加到,windows 环境变量 path中, D:\Android\android-sdk_r3-windows\android-sdk-windows\tool ...

  7. url参数解析

    http://happycoder.net/parse-querystring-using-regexp/ http://www.cnblogs.com/babycool/p/3169058.html ...

  8. 借助Photoshop,Illustrator等设计软件进行WPF图形图像的绘制

    原文:借助Photoshop,Illustrator等设计软件进行WPF图形图像的绘制 本文所示例子是借助第三方设计软件,制作复杂的矢量图形,转成与XAML酷似的SVG,再转换成xaml而实现的. 这 ...

  9. 使用WPF实现3D场景[一]

    原文:使用WPF实现3D场景[一] 在这篇文章里,将介绍如何实现一个简单的三维场景,一个三维的空间,包括空间内的三维物体的组合. 首先介绍一下一个三维场景里的基本元素: 先是定义一个简单的三维的场景环 ...

  10. Oracle 11g系统分区表中的新功能

    在11g有一个新的特点是分区表系统.下面做一个实验: SQL> select * from v$version; BANNER --------------------------------- ...