WPF四年,尤不足以替代WinForm
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的更多相关文章
- WPF 四种尺寸单位
原文:WPF 四种尺寸单位 像素 px 默认单位可以省略 厘米cm 英寸 in 点 pt 1in = 96px 1cm=96/2.42px 1pt=96/72px
- [WPF]建立自适应窗口大小布局的WinForm窗口
编写WinForm程序时,都会碰到一个问题.就是WinForm窗口在不同分辨率下的大小问题.举例说明,你编写的WinForm窗口在1024×768下是合适.匀称的.不过,如果用户的计算机的分辨率为14 ...
- (四十二)c#Winform自定义控件-进度条扩展
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- (四十九)c#Winform自定义控件-下拉框(表格)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- (四十六)c#Winform自定义控件-水波进度条-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...
- (四十五)c#Winform自定义控件-水波图表
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- (四十八)c#Winform自定义控件-下拉按钮
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...
- 练手WPF(四)——贪吃蛇小游戏的简易实现(下)
八.生成新的单节蛇身我们这里先说说游戏小原理好了,游戏运行后,通过计时器事件不断生成新的单节蛇身类SnakeNode,添加到List中的0位置,原来的蛇头变成了第二节.该节新蛇头的坐标通过蛇头前进方向 ...
- 练手WPF(四)——贪吃蛇小游戏的简易实现(上)
一. 游戏界面首先,按照惯例,编辑MainWindow.xaml,先将游戏界面制作好.非常简单:(1)主游戏区依然使用我们熟悉的Canvas控件,大小为640X480像素,设定每小格子为20px,所以 ...
随机推荐
- sparksql dataset
java /** *2.0之后使用sparksession即可,不需要再去创建sqlcontext *@author Tele * */ public class Demo { private sta ...
- range 的实现细节(start、end、step)(左闭右开区间)
range(int start, int end, int step); 返回的区间是 [start, end) 要求步长为 step,三个参数均为整数, 在底层实现时,最终返回的区间元素的数目应当为 ...
- 【records】10.9-10.16
.
- XCode5.1.1怎样实现代码块自己主动排版
1.问题描写叙述 在开发中常常遇到代码块须要排版的情况,假设一行一行缩进就太out了,但在xcode中怎样实现还真不知道 2.解决方法 2.1选中须要排版的代码块 2.2单击"Editor ...
- Sleep(0)的妙用
在线程中,调用sleep(0)可以释放cpu时间,让线程马上重新回到就绪队列而非等待队列,sleep(0)释放当前线程所剩余的时间片(如果有剩余的话),这样可以让操作系统切换其他线程来执行,提升效率. ...
- AI2XAML's Bug(sequel)
原文:AI2XAML's Bug(sequel) I wrote an article about AI2XAML's Bug the day before yesterday. This arti ...
- 给WPF示例图形加上方便查看大小的格子
原文:给WPF示例图形加上方便查看大小的格子 有时,我们为了方便查看WPF图形的样式及比例等,需要一些辅助性的格线,置于图形.图像的背景中. 比如下图,就是为了更清晰地查看折线的图形,我们画了用于标示 ...
- 【Android工具类】用户输入非法内容时的震动与动画提示——EditTextShakeHelper工具类介绍
转载请注明出处:http://blog.csdn.net/zhaokaiqiang1992 当用户在EditText中输入为空或者是数据异常的时候,我们能够使用Toast来提醒用户,除此之外,我们还能 ...
- 从JDBC到commons-dbutils
1.前言 玩过Java web的人应该都接触过JDBC,正是有了它,Java程序才能轻松地访问数据库.JDBC很多人都会,但是为什么我还要写它呢?我曾经一度用烂了JDBC,一度认为JDBC不过如此,后 ...
- Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)
一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...