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. request.getSession().getServletContext().getRealPath()的一些坑

    今天是学校机房的服务器上对之前的一个网站升级时发现了一个bug,我自己的机器上用的tomcat8,机房上是tomcat7,结果一运行就开始报找不到文件,最后发现是文件分隔符的问题 原来在代码中涉及到路 ...

  2. hive 分区表与数据产生关联的三种方式

    所谓关联,可以理解为能够使用select查询到 1.load 这是最常用的一种方式 load data [local] inpath "数据路径" into table table ...

  3. node服务器如何部署https证书

    var http = require('http'); var https = require('https'); var path = require('path'); var fs = requi ...

  4. Android中数据库和安装包分离

    我们在做Android应用尤其是商业应用的时候,很多时候都需要后期版本升级,如果我们的数据库文件非常大,比如游戏之类的,这时候就不应该每次版本更新都去重新复制数据库.将数据库和安装包分离,下面来详细介 ...

  5. webpack单独构建scss文件与.vue组件里构建scss的一个坑

    在入口main.js里构建scss是通过引入模块的方式 import './assets/_reset.scss'; import './assets/_flex.scss'; import './a ...

  6. 【29.41%】【codeforces 724D】Dense Subsequence

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. JTextpane 加入的行号

    最近项目需求,在需求JTextPane加入行号等信息,网上找了半天才发现JTextArea加入行号信息.copy正在研究在线程序.他发现自己能够做出改变来改变JTextPane显示行号. 代码: pa ...

  8. OpenCV For iOS 1: 连接OpenCV 3.0

    本文的内容參考Instant OpenCV for iOS结合最新的开发平台完毕. 本系列文章採用的的开发环境为: 1)Xcode 6 2)OpenCV for iOS 3.0.0 alpha 接下来 ...

  9. hx计算机基础

    参考:http://python.jobbole.com/82294/ https://www.jianshu.com/p/aed6067eeac9 1. 操作系统基础题 1)在32位操作系统下,系统 ...

  10. Scala基本语法学习笔记

      Scala语法与JAVA有很多相似的地方,两者也可以相互调用.但是整体感觉Scala语法等简洁.灵活.这里记录下Scala有特点的地方,以备以后查找方便.   参考: 使用 import: htt ...