您的位置:首页 > 其它

WPF 设计经验总结

2013-10-16 10:46 197 查看
Template
模板是一个可视化控件结构定义,也就是最终界面显示的可视树中控件结构。主要分为两个,一个是DataTemplate,一个是ControlTemplate。
DataTemplate用于为某一类数据定义可视化控件结构。而ControlTemplate则是为某一种类型的逻辑控件定义可视化控件结构。一般情况下,使用ControlTemplate的场景要远远多过DataTemplate。
那么如何设计一个ControlTemplate中的控件结构呢?其实分两步,第一步,设计这个控件的静态结构;第二步,设计控件的动态行为。其实都很简单,使用MicrosoftExpressionBlend这个专业的WPF/Silverlight设计工具进行界面设计,拖拖拽拽就搞定了。
这里要注意的是可视树中的动态行为。主要有两种,一种是模板内部根据各可视控件状态变化而变化的属性设置,可以直接编写在ControlTemplate的Triggers中,Blend中则可以直接在Trigger面板中进行设计;而另一种行为则需要通过与外层逻辑控件的交互完成。交互的方式有:直接绑定逻辑控件属性、路由命令、路由事件、PART_设计约定。
后三种方式是必须要编写代码才能完成的行为。虽然它们并不是设计人员的工作,但是它们是连接开发与设计的桥梁,鉴于它们的重要性,这里还是专门说明一下:
路由事件
在设计自定义逻辑控件时,可以在类型的静态构造器中使用EventManager.RegisterClassHandler来处理内部可视树中所有元素的路由事件。举个简单的例子:在Button类型的设计代码中,为LeftMouseButtonDown事件注册了处理函数,并转换为自己的Click事件,这样,点击Button内部所有可视控件时,才会触发Button的Click事件。
这是一种逻辑控件主动去处理或转换可视控件行为的方式。

路由命令
我认为这是一种可视控件主动挑选命令,而逻辑控件被动执行命令调用的方式。
机制是这样的:控件开发人员为逻辑控件设计了相应的一些行为,但是他们并不知道设计人员会在可视树中用哪一个具体的元素来执行这个行为。这时,开发人员为逻辑控件编写一个路由命令,并在类型静态构造器中为该命令注册处理函数执行相应的控件逻辑。设计人员则只需要在设计控件模板时,为具体元素设置Command即可。这样,由于命令也是通过路由事件来进行路由的,所以内部的可视树控件执行命令时,会一直路由到上层的逻辑控件上,并被相应的逻辑处理。达到可视树控件与逻辑控件交互的效果。

PART_逻辑控件设计约定
当开发一个自定义控件时,如果知道这个控件对应的模板中,必须要有一个某一类型控件,这时我们就可以要求模板设计人员必须在模板中添加该类型的控件,并以一个固定的名称命名。这样,开发人员就能在逻辑控件的ApplyTemplate方法中通过Template.Find找到对应的控件,然后就可以对它进行事件监听、属性控制等操作。而连接逻辑控件、模板中可视树控件的那个名字,为了和一般的命名区分开并显示其重要性,需要使用“PART_”起头。
例如,ComboBox就在类型设计时,指定了至少需要以下两个控件,才能发生正常的下拉行为:





Style
样式本质上是对控件的一组属性设置集合。
当我们设计好一个Style后,可以把它应用到对应控件的许多实例上,那么就算是通过Style默认设置好了这些属性。另外,Style还提供了Trigger,可以实现简单地属性变更时设置其它属性的功能。一般较少使用到EventTrigger。
Style中我们常常看到的最长的一个属性设置就是设置Template属性,即控件的模板。虽然他们俩往往出现在一起,但是Style跟Template其实没有直接的关系,Style所做的只是简单地设置一下控件的Template属性值而已。

有些朋友会问:要达到同样一个效果,我们也可以在Template中直接设置视觉控件的属性,例如直接设置边框宽度。那么,为什么还要把一些属性设置编写在Style中,再去让Template中的控件进行模板绑定,这不是太绕了吗?其实,这样做的好处是使得模板中视觉控件的属性值不会被写成固定值,可以随着外层逻辑控件属性值的变化而变化。这样,当我们直接给逻辑控件设置边框宽度时(本地值),模板中的可视控件就会使用这个更高优先级的值来显示边框。

自定义控件
在开发实际项目时,一般都会遇到要开发自定义控件的情况。相关内容上面已经都谈到了,其实挺简单的:
想好逻辑控件要提供的功能。

思考这些功能需要为模板设计人员提供哪些接口,一般是:依赖属性、路由命令、PART_控件约定。(参考上面的Template设计。)

交互机制确定后,就可以编写相应的后台逻辑控制代码以及默认的控件样式(含模板)。

REF
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: