WPF简览

WPF简览

离开Flex开发已经快两年了,从RIA刚开始兴起就一直做Flex,当初热火朝天的场面还历历在目,往事如斯,只能感叹IT技术变化之快!这两年用WPF开发Windows桌面应用,一开始只是需要它,随用随查而已,没有真正看。最近才有点时间,准备好好学习学习,本来想把WPF和Flex做一个对比,但是想想这样可能会比较杂,所有决定就WPF单独写一篇文章吧。今天先写WPF的 ,然后再写Android、Flex、Java Swing,以纪念这些年使用的技术!

运行环境

WPF用于开发Windows桌面应用,只能在Windows平台运行。当初RIA兴起的时候,微软也提出了一个RIA方案,叫做Silverlight,是WPF的缩减版,可以跑在IE浏览器上,当然也不跨平台。而现在移动互联网的风潮一起,带来了Windows 8和Windows phone 8,Metro App出现了,虽然开发环境不是WPF,API也重写了,但是设计思想和WPF差不多。

开发语言

WPF主要用C#开发,为了开发视图的方便,Xaml标签语言被加入进来。所以用Xaml设计视图,用C#写视图之外一些逻辑什么的。此外WPF可以直接调用C++ Managed库, 也可以调用Win32函数,这样一些C#不容易实现的功能,就可以封装到C++库里,方便调用。

C#有一些特性挺实用,比如代理,相对于Java来说,不知道灵活多少倍;在.NetFramework 4.5中还新增了异步操作,不过还没怎么用。

线程模型

WPF支持多线程,一个WPF程序启动来之后,什么都不干,就会有两个线程:绘制线程、UI线程。

首先来看绘制线程,如果业务逻辑导致视图发生变化,绘制操作就会扔到一个队列里,绘制线程从队列读取操作,进行绘制。但是从开发者角度,我们是看不见这个绘制线程的,当然也控制不了,所以如果您想知道特定的一次绘制什么时候完成,基本没戏。

UI线程就是所谓的主线程、 只有在这个线程内才能进行视图的操作。所以为了保证视图的反应速度,一般很长时间才能完成的任务,最好分配到其他线程,完成后再通知主线程更新UI。Android的线程模型也是这样,只不过,在和主线程通信上,WPF和Android的实现方案不一样,C#的代理,这个时候派上了用场,极大的提高了开发效率。

视图绘制

WPF建立在DirectX 之上,根据GPU支持DirectX的不同,尽可能多地采用硬件加速。WPF把视图渲染的硬件加速情况分为三个级别:

0:全部用CPU渲染视图;

1:部分用CPU,部分用GPU;

2:全部用GPU。

Visual对象为WPF提供了绘制支持,它储存了一个绘制操作列表,当属性改变的时候,如果影响到了视图显示,该操作列表会被更新,但是不会立即绘制,而是把操作列表仍给绘制线程,因为有可能绘制线程可能还有其他绘制操作,所以不会马上绘制,WPF也会优化这些绘制操作,减少重绘。

绘制顺序: 视图绘制从位于可视化树中最顶层节点中的可视化元素开始遍历,然后将按照从左到右的顺序遍历它的子级。如果某个可视化元素有子级,则将先遍历该可视化元素的子级,然后再遍历其同级。也就是说绘制顺序是先父亲后孩子,先左后右。

视图布局

布局分为两个阶段:Measure和定位。Measure用来决定视图的尺寸以及子视图的尺寸。在定位阶段,父视图根据测量结果来决定每个子视图的位置和最终尺寸。WPF中每一容器都提供了自己的MeasureOverride和ArrangeOverride方法来实现自己的布局行为。Measure阶段的最终目的是得到所有子控件的DesiredSize, 它将被用于定位。

具体到代码,可参考如下实现:

protected override Size MeasureOverride(Size availableSize)
    {
        Size panelDesiredSize = new Size();
        foreach (UIElement child in InternalChildren)
        {
            child.Measure(availableSize);
            panelDesiredSize = child.DesiredSize;
        }
        return panelDesiredSize ;
    }
    protected override Size ArrangeOverride(Size finalSize)
    {
        foreach (UIElement child in InternalChildren)
        {
            double x = 50;
            double y = 50;
            child.Arrange(new Rect(new Point(x, y), child.DesiredSize));
        }
        return finalSize; // Returns the final Arranged size
 }


风格和外观

WPF用ControlTemplate来定义控件的外观,用Style改变控件的属性或者设置触发。这些都挺好,受不了的是Xaml的纵向排列风格,如果Style定义太多,或者ControlTemplate层次多一点,太难看,我这眼神真受不了,怀念Flex的简洁啊。并且WPF的State支持太差,和Flex相比,差的十万八千里。

控件结构

WPF控件设计采用了MVVM模式,它是MVC的进化版本,去掉Controller,加入了ViewModel,可以把ViewModel认为是写视图逻辑的地方,这样就可以很好的理解了。每一个控件都有它的数据模型DataContext, 可以使用数据绑定来更新视图,也可以用DataTemplate来定义怎么显示数据。此外,不能不提Command,控件的动作绑定到Command,使得ViewModel能够响应视图的动作,并且使得视图和ViewModel更没有互相可见的必要了。

事件模型

WPF事件派发也是一个U字形,支持Tunneling、Direct、Bubbling(对应Flex的Capturing、Targeting、Bubbling),不过我用WPF的事件很少,主要是用Action,为什么呢? 可能是因为我懒吧,新建一个事件,首先需要定义这个事件(一大长段代码),其次需要创建对应的事件参数类,当我真正需要派发这个事件时候还需要构造这个参数对象。太多繁杂的代码,可能别人没这个感觉,当你用过Flex,就知道我的心情啦!说到这里,就多说几句,因为之前我没在Windows平台开发过,以前都是Java啊, As3啊。后来,用C#开发WPF,也接触到其他微软的技术、文档、API。总的感觉文档不友好、API巨复杂,干一点小事,就需要写N多代码,对于微软这些人我只能无语、膜拜了!

 

控件生命周期

WPF控件有三个生命阶段: Initialized、Loaded、UnLoaded,它们对应三个事件。

Initialized发生在控件被构造完成的时候,这个时候控件的一些属性都被赋值了,xaml定义的子视图也被初始化了,但是一些动态属性,比如数据绑定的还没有,因为本来数据绑定的不知道什么时候有数据。

当控件布局完成,正准备绘制的时候,Loaded事件被激发。Loaded事件可以发多次,比如控件被移除,然后又加入到视图列表中。

Unloaded被激发的时候,就是控件被移除的时候,这个时候控件的父亲已经不存在了。

总结:

总的来说,WPF还是不错的,Xaml里不能写代码,少了灵活性,但是保证了MVVM模式的更好运用。此外,WPF的绘制为开发隐藏了很多复杂性,但是隐藏的太封闭,加入一些可定制接口就更好啦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WPF(Windows Presentation Foundation)是一个用于创建可视化界面的技术,它提供了丰富的控件和布局选项,使界面设计变得简单而灵活。 首先,在WPF中,可以使用XAML(eXtensible Application Markup Language)语言来定义界面的结构和外观。通过使用XAML,您可以使用标签和属性的方式来创建界面元素,例如按钮、文本框、列表框等。这种声明式的方式使得界面设计变得直观和易于理解。 其次,WPF提供了许多内置的样式和模板,可以轻松地对界面元素进行自定义和美化。您可以使用样式来定义按钮的颜色、文本框的边框样式等;也可以使用模板来完全改变控件的外观和布局方式。这样,您可以根据应用程序的需求和风格要求来设计界面,使其与众不同。 此外,WPF还支持数据绑定,使界面和数据之间的绑定更加简单和自动化。您可以绑定界面元素的属性到数据源,当数据源的值改变时,界面元素也会自动更新。这样,您可以实现动态更新界面的功能,无需手动干预。 最后,WPF还提供了强大的布局管理器,例如StackPanel、Grid和DockPanel等。这些布局管理器可以帮助您在界面中灵活组织和排列控件,使其具有良好的可读性和可维护性。您可以使用这些布局管理器来创建简单的界面,例如在窗口中添加按钮和文本框,以及控制它们的布局方式。 总的来说,WPF简单的界面设计主要是通过使用XAML语言、内置样式和模板、数据绑定以及布局管理器等功能来实现。这些功能使得界面设计更加直观、灵活和易于维护,可以满足各种应用程序的需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值