wf框架编程(设计器部分)

 

五、工作流设计器

1 Net设计器基础框架

.net设计器基础框架所在的命名空间是System.ComponentModel.Design,而wfasp.netwin from这三种设计器架构都是建立在.Net本身提供的基础框架之上。

wf设计器框架所在的命名空间是System.Workflow.ComponentModel.Design,相关类都在这个NameSpace里面。在研究wf设计器之前,我们先看看Winform设计器。对Winform设计器的研究,对WF设计器的理解很有帮助。

1.1   Winform设计器设计:

曾经研究过几天SharpDevelop一个免费开源的IDE开发环境,并且有类似eclipse的插件思想。在这个开源IDE里面有比较完整的Winform设计器实现。Winform

IDE主要依靠下面几个接口和类实现。只要实现了相关的接口和抽象,.Net框架会帮助我们实现Winform设计器。很像模板方法。相应的接口和类为:

Winform设计器结构

ü         DesingerHost:

1.服务管理:服务容器和服务提供者

2.组件管理和事务管理

ü         ISite

绑定组件和容器,DesignerHost中所有的服务都可以通过ISite(GetService)得到

ü         IServiceProvide

ü         IDesinger

提供定制服务,设计期在组件的上下文菜单中添加菜单命令,添加的组件实现操作

Initialize方法中与ICompont关联

工具箱实现:      

ü         IToolboxService

工具箱服务,主要目的是存储ToolboxItem

如何填充工具箱?

要使用ToolboxItemFilterAttribute

AddToolboxEntrieslistbox.Items.Add(new SelfHostToolboxItem(entry)

CategoryNames:工具箱类别属性

AddCreator:

其中的WorkflowDesignerControl我觉得是Mediator模式的应用

ü         选取服务

相关assembliesCCU的容器:TypeProvider

大家可以downSharpDevelop的源代码看看,有本书专门介绍这个的。

2 WF设计器

WF设计器的实现思路主要是每个Activity对应的ActivityDesigner和驻留环境(Designer Surface),这也为我们实现基于WebWF设计器提供了思路,就winform环境和webform环境比较,AcitivityDesinger是不变的,变化的是驻留环境。很长时间没有接触WF了,这里讨论的环境是Winfrom下的,以后有机会做的Web环境下再整理吧。


Wf设计器结构

2.1 Activity Designer

Activity关于默认的DesignerAttribute声明是Designer(typeof(ActivityDesigner), typeof(IDesigner)Designer(typeof(ActivityDesigner), typeof(IRootDesigner)

我们如果实现自定义的Acitivity,一般从Activity继承就可以了,不需要重新写。由于ActivityDesigner的设计表现为简单矩形,所以我们看到的活动都是简单矩形的样子,当然我们也可以修改的很漂亮。对应复合活动,如图,从CompositeActivityDesigner上继承下来Desinger有好几个,都有自己的设计表现,其中:ParallelActivityDesigner表现为所有子活动并行;SequenceDesigner表现是自动以顺序方式呈现子活动。

如果是特殊的复合活动,可能需要自己实现Desinger。这里觉的例子是wf本质论上的,大家也可以比较书看一下,电子书是可以免费下载的。例子中要实现自定义的PrioritizedInterleave,设计表现是需要在设计器上表现出优先级关系,由于现有类库缺乏支持,所以就需要自己实现特点的Acitivity Designer.

如何实现自定义ActivityDesigner

PrioritizedInterleaveDesigner例子中,设计意图是点自活动可以在PropertyGrid中设置Priority属性,根据Priority值,子活动位于不特点位置   

可以通过PropertyGrid设置属性

       1.IExtenderListService中加入特定IExtenderProvider。见类图。

       2.特定IExtenderProvider实现

              通过ProvidePropertyAttributePropertyGrid关联

              IExtenderProvider.CanExtend作为是否使用属性的依据,如果为truePropertyGrid控件会查找extender类中的Get<PropertyName>,Set<PropertyName>方法,实现和Acivity属性的交互。

Wf还没有开源,猜测这里这里使用AOP代码织入并使用了Template模式。

       3.Activity的声明使用自定义的ActivityDesignerDesigner(typeof(自定义ActivityDesigner), typeof(IDesigner)

              例子中PrioritizedInterleaveDesigner继承自CompositeActivityDesigne,所以对PrioritizedInterleave的声明,实际上对整个复合活动的声明

              CompositeActivityDesigner.ContainedDesigners

右键菜单修改属性

       1.实现IDesignerVerbProvider接口

       2.初始化活动的时候IDesignerVerbProviderService.AddVerbProvider(IDesignerVerbProvider);

       3.接口实现

                     通过ActivityDesignerVerb.Properties得到Activity

                     针对这个Activity get并修改后Set

       4.PerformLayout使修改生效

修改设计器图形(复合活动和基础活动都可以修改)

       1.对于复合活动override Glyphs方法,得到ActivityDesignerGlyphCollection

                     ActivityDesignerGlyphCollection.Add(DesignerGlyph);

       2.DesignerGlyph的实现

                     override方式实现DesignerGlyphGetBoundsOnPaint方法

       3.对于简单活动,直接override实现ActivityDesignerOnLayoutSize,OnPaint方法

                     OnLayoutSize:返回大小

                     OnPaint:实现了一些必要的绘图功能

                     GetBounds:返回代表图形边界的矩形

修改设计器布局

       重载Acitivity DesignerOnLayoutSizeOnLayoutPosition

       OnLayoutSize返回设计器的合计大小尺寸,OnLayoutPosition计算出子活动的偏移。

设计器主题

1.实现特定的ActivityDesignerTheme

2.再通过ActivityDesignerThemeAttribute注入

3.ActivityDesigner.OnPaint中可以调用Theme

工具箱

       默认是通过ToolboxItemAttribute指向ActivityToolboxItem

       如果有特殊需求,例如在托拽的时候要实现复合控件可以继承ActivityToolboxItem,并在CreateComponentsCore中实现

                     这时候ToolboxItemAttribute指向自定义的ActivityToolboxItem

       使用ToolboxBitmapAttribute可以在工具箱实现自定义视图

2.2 驻留设计器

Designer Surface:职责是管理Designer Host,管理与用户交互(得到view,得到host,异步加载Designer加载器)

Designer Host的职责

1.管理IComponent和相关的IDesigner之间的交互;

2.是一个服务容器,提供取消、剪切板功能和其它活动设计器需要的功能。

事务管理

组件管理:CreateComponentGetDesignerGetType

设计器的加载和管理

             // 摘要:

        //     在激活此设计器时发生。

        event EventHandler Activated;

        //

        // 摘要:

        //     在停用此设计器时发生。

        event EventHandler Deactivated;

        //

        // 摘要:

        //     在此设计器加载完文档时发生。

        event EventHandler LoadComplete;

Designer View的职责

1.呈现各种ActivityDesigner,向各个ActivityDesigner发送消息

2.窗体管理、命令路由、窗体滚动、托放、滚动、布局、打印和打印预览

ISite的职责是绑定组件和容器,DesignerHost中所有的服务都可以通过ISite(GetService)得到

IServiceContainer是服务容器,可以形成树,promote参数true,服务的添加和删除操作会提交给基容器,这些接口的实现思路和winfrom的设计器实现思路非常像。

2          设计器序列化

VS一样,流程设计出来必须要持久化保存,下次使用或者修改的时候通过反序列化操作,我们可以得到曾经设计的流程。

我们可以将活动树序列化为XAML或者代码(默认),甚至可以序列化为(BPEL,DSL)等领域描述语言。序列化为什么格式,可以在AcitivityAttribute中指定。

TypeCodeDomSerializer:序列化为代码

WorkflowMarkupSerializer:序列化为XAML文件


设计器序列化使用的类库

4 代码生成

如果流程中存在Code Activity,那么还需要设计器能动态生成代码。如果指定了TypeCodeDomSerializer,也需要动态代码生成,最后整个WF活动才能通过编译成为.Net下的Assembly

活动代码生成在验证后调用C#代码编译前执行,活动代码生成实际上是给了一个使用CodeDOM生成代码文件的机会。代码生成下次说吧。

posted on 2008-05-08 16:56  lodestar  阅读(4540)  评论(9编辑  收藏  举报

导航