转:
http://blog.csdn.net/dotnetWalker/archive/2010/03/31/5438704.aspx
Silverlight 3这个版本刚释出时,让人感到惊艳的新功能很多,但要说哪一项技术可以彻底改变和提升开发人员与设计师之间的合作方式,并且能够达成真正的模块化并且提高程序代码重用性,对于Silvelright应用程序(或网站)的开发有着决定性的关键影响,那非Behavior技术莫属了。
几乎我的所有朋友(和客户们),对于Silverlight加入这个新功能无不大加赞许,它一举解决了过去designer(设计师或美术人员)和developer(程序设计师)长期的合作与沟通问题,找出了一个可以让设计师和开发人员好好沟通并且互相配合的方式(这部分是Behavior对于Designer的价值);同时,这个技术也提供了另一种系统开发的可能性,让不具备高度程序开发技术的开发人员,也可以撰写出自己需要的系统,并且让软件重用性大幅提升(这部分则是Behavior对于Developer的价值)。
Behavior可以把一些常用的行为封装成可重复使用的组件(Component),这个组件从技术面来说,当然只是没有外观的一组类别(Class),而开发人员或设计师可以在Blend 3当中将这个类别的对象实体(instance)『套用(Hook)』到某一个控件上,使得套用了该Behavior的控件可以不须撰写任何程序代码,就可以立即拥有(达成)一些和使用者互动的行为。
例如说,当我们把『拨放动画』这一个Behavior套用在Button这个对象上之后,当用户点选(Click)Button,则动画就自动被拨放了,不用写程序,使用起来就跟拖曳控件一样自然。这让设计师(Designer)有机会可以独立的建置Silvelright应用程序,一扫过去设计师必须时时刻刻依赖开发人员而无法独立运作的窘境。
这也让我们有机会把『行为』对象化。请注意,在传统的面向对象程序设计观念中,过去我们只把UI层的需求组件化成为控件,而现在我们则可以进一步地把实现(达成)特定功能的代码段,例如发一封信、拨一段动画、将窗体上的数据存入数据库…等『动作』,也组件化成为『行为』(其实上在Silverlight中有Action和Behavior这两种实现方式可供选择,容后说明)。
如此一来,除了设计师之外,若开发人员擅用Behavior机制也将可以让整个Silverlight应用程序的设计更加的结构化与对象化,我们可以把常用的『动作』封装起来重复使用,由资深程序设计师来设计Behavior,而初阶或是UI的程序设计师则负责使用这些Behavior来开发程序。
在理想状况下,Designer(设计师)或domain expert(特定领域的专家,例如财会人员、HR人员、或MIS)甚至可以完全不需要具备程序设计的观念,只需要了解基础的事件(Event)观念,就可以顺利的开发出一套系统,若需要实现特定的功能时,可商请developere为他们开发所需要的Behavior,designer只需要取得这些Behavior并使用即可。
理想状况离现实很遥远吗?一点也不,依据我实际针对企业讲授Silverlight课程的经验来看,Behaivor几乎掳获所有Designer和domain expert的心,甚至我们几乎可以期待这样的概念衍生到Windows Form/Web Form的应用程序开发当中。
OK,说了这么多,我们还是先来看看该怎么在开发环境当中使用Behavior技术。当然,就单纯的Silverlight开发人员(不管是Designer或是Developer)来说,开发环境安装好Blend 3是最低的要求,同时当您安装了Silverlight 3 SDK以及Blend 3 SDK、Silverlight 3 Toolkit等套件之后,您可以直接在Blend 3当中建立一个Silverlight应用程序,接着在场景中布置一个Button和一个TextBlock,并且随意设计一个动画。
接着,请切换到Assets页标签,若您有正确的安装Blend 3 SDK,您会看到Assets页卷标下有Behaviors选项,在列出的项目中,你会看到有一个ControlStoryboardAction:
请点选它并拖曳到Button上,然后切换到Object and Timeline页标签,您会发现Button控件底下多了个ControlStoryboardAction对象
接着点选该对象,切换到属性窗口,您接着会发现,可以透过开发环境来设定ControlStoryboardAction对象的属性(请注意不是Button的属性,别点错):
完成之后,请先建置(Build)此应用程序,成功后请接着执行此应用程序,您会发现在不需要写任何程序代码的状况下,当使用者按下Button1(也就是Button1的Click事件触发后),Storyboard动画就自动被播放了。
如果您仔细观察Action的设定窗口,会发现其实场景中任何控件(不只是Button)的任何事件(不只是Click)都可以做为特定Action的触发条件。而每一个Actionr都代表着一种行为,而程序设计人员(developer)可以设计出各式各样的Action,让设计师(Designer)直接使用。
那Trigger、Action、Behavior三者之间究竟有何关系呢?
从上面的操作中我们可以知道,Action是经过程序设计师封装好的某种行为(功能),我们可以把一些常用的代码段,例如上面用到的『动画拨放』、或是先前我们提过的『发一封信』、或『将窗体上的数据存入数据库』…等『功能』整理成一个个的Action,而开发人员只需要把Action拖曳到特定的对象上即可使用。
当然,拖曳到目标对象上之后,还得要设定这个Action的相关信息,也就是该Action的属性(如果有的话),以及该Action被触发的时机,而这就是所谓的Trigger了。
在Silverlight中,预设的Trigger有底下几种:
1.EventTrigger:最常用的触发器,可选择在控件的特定事件发生时触发,例如Loaded、MouseLeftButtonDown、GotFocus…等。
2.TimerTrigger:可设定每n毫秒触发一次,总共要触发几次或随时间持续触发。
3.KeyTrigger:可设定在特定按键被按下时触发,可捕捉到键盘上的一般按键与功能键,亦可抓取Ctrl, Alt等组合控制键。
4.StoryboardCompletedTrigger:在特定动画拨放完毕后触发。
请注意,这些Trigger是配合着Action使用的,你会发现,每一个Action都可以透过Blend设定Trigger,并透过Trigger来触发执行此Action,如此一来,我们就可以相当灵活的在场景中特定控件的特定事件发生时,来执行特定工作。
也就是说,在这个机制下,只要程序设计师预先写好Trigger与Action,Designer就可以在完全不撰写任何程序代码的状况下,来开发出一个Silverlight应用系统或网站。
我们刚才提到了Action与Trigger,那Behavior呢?难道Behavior不需要Trigger吗?其实不是的,应该说,Behavior是内建(包含)了Trigger!!!
你会发现当场景中的某一个对象被套用了Behavior之后,不需要设定任何Trigger,该对象就会自动拥有某种功能,就好像我们刚才介绍了的MouseDragElementBehavior一样,当该Behavior套用在某个对象上,该对象就直接支持拖曳行为了,因此,你可以将Behavior直接想象成Trigeer与Action的结合。
我们先谈到这边,下一篇则要来介绍Action的开发方式...
从前面的介绍中我们可以知道,当我们设计好了Action或Behavior之后,其实不仅是设计师(Designer)可以使用,一般开发人员在撰写应用程序时,也可以将常用的功能封装成了Action或Behavior,让其他开发人员直接套用。
我们在这边看一个简单的例子,从这个例子当中我们也来看如何设计Action。请参考底下这个画面:
这是一个很典型的简单输入画面,使用者可以在TextBox中输入文字,但是,当用户点选TextBox的时候,得先把TextBox中的文字先清空后才能输入,体贴一点的程序,会在用户点选该TextBox时,就直接让该TextBox中的文字变成『选取』状态,这样使用者就可以直接输入了:
当然,要达成这样的功能相当容易,只需要在TextBox的GotFocus事件中撰写『this.TextBox1.SelectAll();』即可。但是每一个TextBox都要这样写,显然很麻烦,如果可以跟刚才一样,把一个对象(Component)直接拖曳到TextBox上,该TextBox就自动具有此功能,岂不挺好?
是的,我们紧接着就来看如何设计这样的Action。
请先建立一个Silverlight项目(当然您也可以在现有的Silverlight项目中直接建立Action或Behavior类别,不过为Action或Behavior建立一个独立的项目是比较理想的选择),该项目请选择『Silverlight Class Library』即可,接着,请在该项目中建立一个Action类别,当您在项目中选择Add New Item时,可以找到Blend分类下的Action Template,我们建立一个名称为『TextBoxAutoSelectAction』的Action,你会发现建立出来的类别如下:
请将TriggerAction调整成TargetedTriggerAction,并将<DependencyObject>改为< TextBox >。
TargetedTriggerAction是一个泛型类别,其中的<DependencyObject>则可设定为我们默认的目标对象。例如,我们现在设计的这个TextBoxAction主要的使用对象是TextBox,因此我们可以写成『TargetedTriggerAction<TextBox>』。而继承TargetedTriggerAction这个类别必须要实作Invoke方法,Invoke方法是该Action被触发时,要执行的动作。
接着,我们在Invoke方法中撰写的程序代码如下:
其中的Target是目标对象,也就是我们将来把该Action拖曳到TextBox时所指定的控件,而我们针对该Target呼叫其SelectAll()方法,来选取其中的文字。就这样,完成了。
接着我们编译建置该项目,然后在我们的Silverlight主项目当中,引用(Add Reference)建置好的.dll,
当项目中正确的引用了该.dll之后,就可以开始使用了,请切换到Blend 3,依照刚才我们先前介绍如何使用Action的方式,切换到Assets页标签下,您会看到我们刚才建立的这个Action已经出现在选项当中(如果没有找到,请检查一下是否有正确的引用该.dll或是该项目)。这时候,您可以直接将该Action (TextBoxAutoSelectAction)拖曳到画面中的TextBox上:
拖曳上去之后,切换到属性窗口,可以设定该Action的属性:
请将Trigger中的EventName设定为GotFocus,接着将TargetName设为TextBox1,整个设定的意思是:当TextBox1的GotFocus事件被触发时,在TextBox对象上(将TextBox1对象视为Target)执行该Action(也就是让TextBox中的文字被选取)。
经过这样的设定后,应用程序执行时只要用户一点选TextBox1或是透过Tab键切换到TextBox1(GotFocus事件被触发),TextBox中的文字就自动被选取了。未来我们只需要把这个Behavior拖曳到任何TextBox对象上,就可以不须撰写任何程序代码,在需要的时候执行此Action。
尽管这个范例似乎很简单(只是选取文字),但重点是透过这样的技术,开发人员可以利用此机制,或设计出各式各样的Action,供其他Developer或Designer使用,诸如影片的控制(播放、暂停)、甚至是各种窗口或是动画的处理(例如对象的淡入淡出…)。总括来说,Action是一个相当好用且重要的功能,值得开发人员广泛的使用在自己的项目当中。
Silverlight 3这个版本刚释出时,让人感到惊艳的新功能很多,但要说哪一项技术可以彻底改变和提升开发人员与设计师之间的合作方式,并且能够达成真正的模块化并且提高程序代码重用性,对于Silvelright应用程序(或网站)的开发有着决定性的关键影响,那非Behavior技术莫属了。
几乎我的所有朋友(和客户们),对于Silverlight加入这个新功能无不大加赞许,它一举解决了过去designer(设计师或美术人员)和developer(程序设计师)长期的合作与沟通问题,找出了一个可以让设计师和开发人员好好沟通并且互相配合的方式(这部分是Behavior对于Designer的价值);同时,这个技术也提供了另一种系统开发的可能性,让不具备高度程序开发技术的开发人员,也可以撰写出自己需要的系统,并且让软件重用性大幅提升(这部分则是Behavior对于Developer的价值)。
Behavior可以把一些常用的行为封装成可重复使用的组件(Component),这个组件从技术面来说,当然只是没有外观的一组类别(Class),而开发人员或设计师可以在Blend 3当中将这个类别的对象实体(instance)『套用(Hook)』到某一个控件上,使得套用了该Behavior的控件可以不须撰写任何程序代码,就可以立即拥有(达成)一些和使用者互动的行为。
例如说,当我们把『拨放动画』这一个Behavior套用在Button这个对象上之后,当用户点选(Click)Button,则动画就自动被拨放了,不用写程序,使用起来就跟拖曳控件一样自然。这让设计师(Designer)有机会可以独立的建置Silvelright应用程序,一扫过去设计师必须时时刻刻依赖开发人员而无法独立运作的窘境。
这也让我们有机会把『行为』对象化。请注意,在传统的面向对象程序设计观念中,过去我们只把UI层的需求组件化成为控件,而现在我们则可以进一步地把实现(达成)特定功能的代码段,例如发一封信、拨一段动画、将窗体上的数据存入数据库…等『动作』,也组件化成为『行为』(其实上在Silverlight中有Action和Behavior这两种实现方式可供选择,容后说明)。
如此一来,除了设计师之外,若开发人员擅用Behavior机制也将可以让整个Silverlight应用程序的设计更加的结构化与对象化,我们可以把常用的『动作』封装起来重复使用,由资深程序设计师来设计Behavior,而初阶或是UI的程序设计师则负责使用这些Behavior来开发程序。
在理想状况下,Designer(设计师)或domain expert(特定领域的专家,例如财会人员、HR人员、或MIS)甚至可以完全不需要具备程序设计的观念,只需要了解基础的事件(Event)观念,就可以顺利的开发出一套系统,若需要实现特定的功能时,可商请developere为他们开发所需要的Behavior,designer只需要取得这些Behavior并使用即可。
理想状况离现实很遥远吗?一点也不,依据我实际针对企业讲授Silverlight课程的经验来看,Behaivor几乎掳获所有Designer和domain expert的心,甚至我们几乎可以期待这样的概念衍生到Windows Form/Web Form的应用程序开发当中。
OK,说了这么多,我们还是先来看看该怎么在开发环境当中使用Behavior技术。当然,就单纯的Silverlight开发人员(不管是Designer或是Developer)来说,开发环境安装好Blend 3是最低的要求,同时当您安装了Silverlight 3 SDK以及Blend 3 SDK、Silverlight 3 Toolkit等套件之后,您可以直接在Blend 3当中建立一个Silverlight应用程序,接着在场景中布置一个Button和一个TextBlock,并且随意设计一个动画。
接着,请切换到Assets页标签,若您有正确的安装Blend 3 SDK,您会看到Assets页卷标下有Behaviors选项,在列出的项目中,你会看到有一个ControlStoryboardAction:
请点选它并拖曳到Button上,然后切换到Object and Timeline页标签,您会发现Button控件底下多了个ControlStoryboardAction对象
接着点选该对象,切换到属性窗口,您接着会发现,可以透过开发环境来设定ControlStoryboardAction对象的属性(请注意不是Button的属性,别点错):
完成之后,请先建置(Build)此应用程序,成功后请接着执行此应用程序,您会发现在不需要写任何程序代码的状况下,当使用者按下Button1(也就是Button1的Click事件触发后),Storyboard动画就自动被播放了。
如果您仔细观察Action的设定窗口,会发现其实场景中任何控件(不只是Button)的任何事件(不只是Click)都可以做为特定Action的触发条件。而每一个Actionr都代表着一种行为,而程序设计人员(developer)可以设计出各式各样的Action,让设计师(Designer)直接使用。
那Trigger、Action、Behavior三者之间究竟有何关系呢?
从上面的操作中我们可以知道,Action是经过程序设计师封装好的某种行为(功能),我们可以把一些常用的代码段,例如上面用到的『动画拨放』、或是先前我们提过的『发一封信』、或『将窗体上的数据存入数据库』…等『功能』整理成一个个的Action,而开发人员只需要把Action拖曳到特定的对象上即可使用。
当然,拖曳到目标对象上之后,还得要设定这个Action的相关信息,也就是该Action的属性(如果有的话),以及该Action被触发的时机,而这就是所谓的Trigger了。
在Silverlight中,预设的Trigger有底下几种:
1.EventTrigger:最常用的触发器,可选择在控件的特定事件发生时触发,例如Loaded、MouseLeftButtonDown、GotFocus…等。
2.TimerTrigger:可设定每n毫秒触发一次,总共要触发几次或随时间持续触发。
3.KeyTrigger:可设定在特定按键被按下时触发,可捕捉到键盘上的一般按键与功能键,亦可抓取Ctrl, Alt等组合控制键。
4.StoryboardCompletedTrigger:在特定动画拨放完毕后触发。
请注意,这些Trigger是配合着Action使用的,你会发现,每一个Action都可以透过Blend设定Trigger,并透过Trigger来触发执行此Action,如此一来,我们就可以相当灵活的在场景中特定控件的特定事件发生时,来执行特定工作。
也就是说,在这个机制下,只要程序设计师预先写好Trigger与Action,Designer就可以在完全不撰写任何程序代码的状况下,来开发出一个Silverlight应用系统或网站。
我们刚才提到了Action与Trigger,那Behavior呢?难道Behavior不需要Trigger吗?其实不是的,应该说,Behavior是内建(包含)了Trigger!!!
你会发现当场景中的某一个对象被套用了Behavior之后,不需要设定任何Trigger,该对象就会自动拥有某种功能,就好像我们刚才介绍了的MouseDragElementBehavior一样,当该Behavior套用在某个对象上,该对象就直接支持拖曳行为了,因此,你可以将Behavior直接想象成Trigeer与Action的结合。
我们先谈到这边,下一篇则要来介绍Action的开发方式...
从前面的介绍中我们可以知道,当我们设计好了Action或Behavior之后,其实不仅是设计师(Designer)可以使用,一般开发人员在撰写应用程序时,也可以将常用的功能封装成了Action或Behavior,让其他开发人员直接套用。
我们在这边看一个简单的例子,从这个例子当中我们也来看如何设计Action。请参考底下这个画面:
这是一个很典型的简单输入画面,使用者可以在TextBox中输入文字,但是,当用户点选TextBox的时候,得先把TextBox中的文字先清空后才能输入,体贴一点的程序,会在用户点选该TextBox时,就直接让该TextBox中的文字变成『选取』状态,这样使用者就可以直接输入了:
当然,要达成这样的功能相当容易,只需要在TextBox的GotFocus事件中撰写『this.TextBox1.SelectAll();』即可。但是每一个TextBox都要这样写,显然很麻烦,如果可以跟刚才一样,把一个对象(Component)直接拖曳到TextBox上,该TextBox就自动具有此功能,岂不挺好?
是的,我们紧接着就来看如何设计这样的Action。
请先建立一个Silverlight项目(当然您也可以在现有的Silverlight项目中直接建立Action或Behavior类别,不过为Action或Behavior建立一个独立的项目是比较理想的选择),该项目请选择『Silverlight Class Library』即可,接着,请在该项目中建立一个Action类别,当您在项目中选择Add New Item时,可以找到Blend分类下的Action Template,我们建立一个名称为『TextBoxAutoSelectAction』的Action,你会发现建立出来的类别如下:
public class TextBoxAutoSelectAction : TriggerAction<DependencyObject> { public TextBoxAutoSelectAction() { // Insert code required on object creation below this point. } protected override void Invoke(object o) { // Insert code that defines what the Action will do when triggered/invoked. } }
请将TriggerAction调整成TargetedTriggerAction,并将<DependencyObject>改为< TextBox >。
TargetedTriggerAction是一个泛型类别,其中的<DependencyObject>则可设定为我们默认的目标对象。例如,我们现在设计的这个TextBoxAction主要的使用对象是TextBox,因此我们可以写成『TargetedTriggerAction<TextBox>』。而继承TargetedTriggerAction这个类别必须要实作Invoke方法,Invoke方法是该Action被触发时,要执行的动作。
接着,我们在Invoke方法中撰写的程序代码如下:
protected override void Invoke(object o) { TextBox TargetObject=Target; TargetObject.SelectAll(); }
其中的Target是目标对象,也就是我们将来把该Action拖曳到TextBox时所指定的控件,而我们针对该Target呼叫其SelectAll()方法,来选取其中的文字。就这样,完成了。
接着我们编译建置该项目,然后在我们的Silverlight主项目当中,引用(Add Reference)建置好的.dll,
当项目中正确的引用了该.dll之后,就可以开始使用了,请切换到Blend 3,依照刚才我们先前介绍如何使用Action的方式,切换到Assets页标签下,您会看到我们刚才建立的这个Action已经出现在选项当中(如果没有找到,请检查一下是否有正确的引用该.dll或是该项目)。这时候,您可以直接将该Action (TextBoxAutoSelectAction)拖曳到画面中的TextBox上:
拖曳上去之后,切换到属性窗口,可以设定该Action的属性:
请将Trigger中的EventName设定为GotFocus,接着将TargetName设为TextBox1,整个设定的意思是:当TextBox1的GotFocus事件被触发时,在TextBox对象上(将TextBox1对象视为Target)执行该Action(也就是让TextBox中的文字被选取)。
经过这样的设定后,应用程序执行时只要用户一点选TextBox1或是透过Tab键切换到TextBox1(GotFocus事件被触发),TextBox中的文字就自动被选取了。未来我们只需要把这个Behavior拖曳到任何TextBox对象上,就可以不须撰写任何程序代码,在需要的时候执行此Action。
尽管这个范例似乎很简单(只是选取文字),但重点是透过这样的技术,开发人员可以利用此机制,或设计出各式各样的Action,供其他Developer或Designer使用,诸如影片的控制(播放、暂停)、甚至是各种窗口或是动画的处理(例如对象的淡入淡出…)。总括来说,Action是一个相当好用且重要的功能,值得开发人员广泛的使用在自己的项目当中。