敬告读者:因为是事件驱动模式的高速学习,高速学习意味着,不系统,不科学,不合逻辑,不一定正确。所以要是有不对的地方,页面下面留言给我,跪谢!
背景介绍:
最近在公司的开发工作中,接手了从别的公司交代过来的代码巨怪,其中主要的技术有 WPF,控制反转框架Spring.net,SqlMap(有点像是ibatis.net),Remoting,作业调度框架Quarz,我们的工作,是把这只怪兽,敲碎,重组并且优化,目标暂时是重构成WebAPI底层和WPF界面两个部分,下面是我学习WPF的过程中,留下的一些很(luan)有(qi)见(ba)地(zao)的笔记。
笔记:
学习开始的时候,我通常要求自己不要分太多精力去关注一个技术的历史,英文全称是什么(Windows Presentation Foundation)这些问题,这个对实际生产,并没有实际作用,我强烈要求自己只关注怎么开始,并且要开始习惯地用 “问题回答框架”(是什么? 为什么? 怎么样? )来执行学习作业。
WPF的“是什么”和“为什么”,我认为需要搞清楚几个事情:
- 明明已经有Winfrom,为什么还要有WPF呢?有什么改进?
- 最直面地,将会用到什么方面的知识呢?
- 同期的技术有什么呢?
1、答:
我是搞Web(asp.net)起家的,Winfrom都不太熟,突如其来的PC界面开发,着实有点措手不及,但是WPF的Xaml界面语言着实让人眼前一亮,既然是ML类语言,那么Xml,Html的语法和Xaml应该如出一辙的,于是剩下的,马上就只剩下标签的熟悉程度问题了,这对Web开发者而言,是个极大的利好消息。
WPF从某个意义上说是很像 Winfrom的,你可以很Winfrom地开发WPF,新建一个WPF解决方案之后,直接拖一个控件(button)到界面上,然后双击增加事件。
但是它也可以很网页地开发某些From,比如想做一个登录窗口,你必然会想到这样子的Html代码:
姓名:<input type="text" id="txtUserName"> 密码:<input type="password" id="txPassword"> <input type="submit" id="btnSubmit" value="提交">
于是这么看来WPF也提供了这样一种类似的结构:
<Button x:Name="btnPageEvent" Content="点我!" Margin="441,0,0,0" Click="btnPageEvent_Click"/>
在这一点上Winfrom给我的感觉是特别麻烦,你通常只能通过拖拽的方式添加控件,如果要写代码添加,disigner.cs的代码可读性真是可以看得人作呕的,这意味着什么,这意味着,界面的开发和代码的开发分离了,而且界面代码的复用能力增强了许多许多。
2、答:
最直面的,当然就是上面提到的Xaml,然后有MVVM框架,然后要像Html+CSS那样谈表现和内容分离,然后要谈SilverLight(虽然当前还没学习到,但是我感觉WPF的动画是让人兴奋的)
3、答:
WPF有几个同窗,WCF,WF,新一期的MVC框架等等,都是非常有竞争力,有吸引力的知识和工具。为什么要知道这个呢?因为我一定会把WPF和WCF
接下来怎么样开始好呢?
首先这不是从头开始自己开坑,这是别人家公司搞了好几年的代码,别人家公司的知(yuan)识(shi)产(ju)权(keng),给你代码已经很对得起你了,怎么可能有文档呢?
实践出真知,当然是要开始写了,才会懂的,我简单地整理了下代码怪兽里面的一些经常出现的控件和单词,通过书籍《WPF编程宝典:使用C# 2012和.NET 4.5(第4版)》,我简单地将他们分到了以下几个类别里面:
- WPF的基本控件(Button,Radio,CheckBox,DataGrid,等等) //(大家都要有的啦!)
- WPF的布局控件(Grid,StackPanel,Border等等) //(布局这个单词在PC的软件上看见是件值得让人感动的事情)
- 元素的绑定(Binding,ObservableCollection) //(MVVM的ViewModel绑定操作)
- 元素的外部资源,样式或者转换器(StaticResource) //(表现和内容分离)
- 事件的触发器(Triggers,EventTrigger,ICommand)
嗯,于是问题来了,我发现经常会有这样的写法:
1 Style="{StaticResource SimpleButton}" 2 CommandParameter="{Binding ElementName=gdTaskList, Path=SelectedItem}" 3 Binding="{Binding CreateTime, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource dateTimeConverter}}"
这时候我不禁不断得吐槽,这都什么鬼啊……
- => Binding里面还套着一个Json格式的对象,对象里面还有一个Binding?
- => StaticResource,这是哪里的Resource?哪里引入进来的呢?
- => Mode, UpdateSourceTrigger, Converter都哪里来的属性,自己带的么?
- => Converter 你又调皮了,怎么又带上一个StaticResource了,这不元素样式的资源么?怎么跑来转换器这了?
不,不能再继续下去了,这样是很凌乱的。人家是大团队,人家绝对不是傻瓜,毕竟是几年的代码,再乱,都有它的章法。我们要暂时放下工作上的这一切,学习一点基础知识才对:
MVVM:
这个东西可能对于传统的程序员们而言会有点难理解,大家都非常习惯MVC的一套,用户向Controler提出请求,然后Controller把View和Model结合在一起带到用户面前;也非常喜闻乐见地用三层开发。
(我的学习顺序或许有点非主流,我是先学习了Web上面的Knockout.js,对MVVM有一个初步的了解,再学习的WPF。)
我是这么理解MVC和MVVM的:
我们做的页面,我们取出来的数据,分别是两个对象,对于MVC来说,我们看到的页面和数据,是Controller从数据中一个一个地找到对应的属性,并且贴到View对应的地方去的,注意是一个一个地找到;而对于MVVM而言,我们看到的页面和数据,就是预先标记好这里要填写什么的页面,然后把数据啪的一下,叠在页面上面。
可能说的不清晰,我举个例子吧,不知道读者小时候有没有见过很老式的投影仪(胶片投影机,见上图),不过现在基本都配备了高级的投影仪和实物投影,我小时候上课的时候,老师会把习题先写在一张透明的胶纸上,然后拿另一张胶纸叠在习题的上面,写上答案。上课的时候老师先把写着习题的一张投影出来,大家做练习,然后,再把写着答案的一张叠在习题的上面,这样就可以对答案了。嗯,我这里讲的就是“叠”的这个操作,这个操作给我的感觉其实很像MVVM的绑定操作。
建立项目:
只有3.5的.net FrameWork才有WPF的,所以代码开发工具最好是2010以上(大家快去下载2015的community版本吧,免费的咯)。
新建项目,就是 文件->新建->项目...
嗯,这个倒是难不倒我……
结束:
嗯,我们还没有写一句代码,就结束了,
确实几个月的收获也不止这么一点,
是的,饭要一口口吃的,笔记也要一点点整理的,
但是我觉得还是开了个好头的,
起码对我来说是的……