Windows Workflow Foundation(四)——(创建自定义活动)(转载)

简介:

WWF包含了一组丰富的通用用户活动,这些能满足绝大多数的场景的需求。但有时,我们还是会碰到需要一些更加自定义的活动的场景。WWF SDK拥有一些可扩展的特性,能使你轻松的创建自定义的活动,并把他们应用到你的解决方案中。在这一节中,我们会编写一个自定义活动,用来根据传入工作流的参数,从网页中下载文本。

创建一个网页解析自定义活动

这个自定义活动会根据传入活动的网页属性集,从网页中下载文本。页面一旦下载完毕,活动就会发出一个网页下载完毕的事件,并把网页数据值发回工作流。

创建WebTearActivity

WebTear类继承自System.Workflow.ComponentModel.Activity。当你定义了一个自定义活动时,把ToolboxItemAttributes属性应用到类上,并指明为ActivityboxItem类型。以下的代码就是一个最小的自定义活动。

None.gifusing System;
None.gifusing
System.ComponentModel;
None.gifusing
System.Workflow.ComponentModel;
None.gifusing
System.Workflow.ComponentModel.Design;
None.gifusing
System.Workflow.ComponentModel.Compiler;
None.gif
None.gifnamespace
Microsoft.Samples.Workflow.Quickstarts.CustomActivity
ExpandedBlockStart.gifContractedBlock.gifdot.gif
{
InBlock.gif [ToolboxItemAttribute(typeof
(ActivityToolboxItem))]
InBlock.gifpublic class
WebTear : System.Workflow.ComponentModel.Activity
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}


定义活动属性

自定义活动属性的定义和WinForm控件属性的定义类似。当你定义一个自定义活动的属性时,使用DependencyProperty来存储属性的属性。这能让各种不同类型的属性都能一致地有效地工作。在实际定义属性时,你可能还会用到DependencyProperty中的方法,所以,不要把这个字段定义成private

活动中的一个属性可以应用许多不同的特性。这些特性通常都是用来支持WWF设计器的工作的。我们的这个属性应用了一下的特性:

1. CategoryAttribute:在设计器的属性窗口中,这个属性位于那个分类下。

2. DescriptionAttribute:设计器属性窗口中显示的属性描述。

3. BrowsableAttribute:这是一个布尔值,指示了是否在属性窗口中显示这个属性。

4. ValidationVisibilityAttribute:指定了如何验证属性的值。验证选项包括:可选Optional、必需Required、隐藏Hidden

5. DesignerSerializationVisibilityAttribute:指定了是否和如何序列化这个属性。选项包括:可见Visible、隐藏Hidden、内容Content

以下的代码示例了如何定义WebPage属性。

None.gifpublic static DependencyProperty WebPageProperty =
None.gif DependencyProperty.Register( "WebPage", typeof(System.String), typeof (Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear ) );
None.gif
None.gif[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
None.gif[ValidationVisibilityAttribute(ValidationVisibility.Optional)]
None.gif[BrowsableAttribute(true
)]
None.gif[DescriptionAttribute("Web page to download"
)]
None.gif[CategoryAttribute("WebTear Property"
)]
None.gifpublic string
WebPage
ExpandedBlockStart.gifContractedBlock.gifdot.gif
{
InBlock.gifget

ExpandedSubBlockStart.gifContractedSubBlock.gif dot.gif {
InBlock.gifreturn ((string)(base
.GetValue(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.WebPageProperty)));
ExpandedSubBlockEnd.gif }

InBlock.gif set
ExpandedSubBlockStart.gifContractedSubBlock.gif dot.gif {
InBlock.gifbase
.SetValue(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.WebPageProperty, value);
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}


重载Execute方法

当你创建了一个自定义活动,运行时,工作流引擎会调用活动的Execute方法来执行活动实际的操作。这个方法是在基类中定义的,但你可以重载这个方法,以适应你的活动的功能。

WebTear活动会在Execute方法中下载请求的网页,并在下载完成后引发一个事件,将页面数据发回工作流。我们需要定义一个PageFinishedEventArgs类用于事件参数,这个类中有一个Data字段用来存放网页数据。这些数据会在之后被工作流中的事件处理函数访问到。一旦数据下载完毕,Execute方法返回一个Status.Closed枚举值,来通知工作流引擎活动已经完成执行了。

一下的代码演示了如何定义PageFinishedEventArgs

None.gifpublic class PageFinishedEventArgs
ExpandedBlockStart.gifContractedBlock.gifdot.gif
{
InBlock.gifprivate string
data;
InBlock.gif
InBlock.gifpublic PageFinishedEventArgs( string
data )
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gifthis.data =
data;
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
public string Data
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
ExpandedSubBlockStart.gifContractedSubBlock.gifget dot.gif{ return data; }

ExpandedSubBlockEnd.gif }
ExpandedBlockEnd.gif}


以下的代码演示了如何实现Execute方法。

None.gifpublic delegate void PageFinishedEventHandler( object sender, PageFinishedEventArgs e );
None.gifpublic event
PageFinishedEventHandler PageFinished;
None.gif
None.gifprotected override
Status Execute(ActivityExecutionContext context)
ExpandedBlockStart.gifContractedBlock.gifdot.gif
{
InBlock.gif System.Net.WebClient client = new
System.Net.WebClient();
InBlock.gifstring
pageData;
InBlock.gif
InBlock.giftry

ExpandedSubBlockStart.gifContractedSubBlock.gif dot.gif {
InBlock.gif// Download the web page data

InBlock.gif
pageData = client.DownloadString(WebPage);
ExpandedSubBlockEnd.gif }

InBlock.gif catch (Exception e)
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gif pageData =
e.Message;
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
// Raise the PageFinished event back to the host
InBlock.gif
PageFinished(null, new PageFinishedEventArgs(pageData));
InBlock.gif
InBlock.gif// Notifiy the runtime that the activity has finished

InBlock.gif
return Status.Closed;
ExpandedBlockEnd.gif}


WebTear活动创建顺序工作流

此时,我们已经创建好了下载网页的自定义活动。现在我们创建一个简单的顺序工作流,来测试一下这个自定义活动的功能。

这个工作流只包含一个活动,就是我们的WebTear活动。要下载的网页地址被传到工作流的Parameters集合中,这个的值用来设置活动的WebPage属性。最后,当活动结束下载后,触发事件,工作流会从事件参数中提取网页数据,并把数据通过Parameters集合中的out参数发回宿主程序。以下代码演示了顺序工作流的实现

None.gifusing System;
None.gifusing
System.ComponentModel;
None.gifusing
System.Workflow.ComponentModel;
None.gifusing
System.Workflow.ComponentModel.Design;
None.gifusing
System.Workflow.ComponentModel.Compiler;
None.gifusing
System.Workflow.Activities;
None.gif
None.gifnamespace
Microsoft.Samples.Workflow.Quickstarts.CustomActivity
ExpandedBlockStart.gifContractedBlock.gifdot.gif
{
InBlock.gifpublic sealed partial class
WebTearActivityWorkflow : SequentialWorkflow
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gifprivate string
webSite;
InBlock.gifprivate
WebTear webTear1;
InBlock.gif
InBlock.gifpublic
WebTearActivityWorkflow()
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gif InitializeComponent();
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private void InitializeComponent()
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gif System.Workflow.ComponentModel.ActivityBind activitybind1 = new
System.Workflow.ComponentModel.ActivityBind();
InBlock.gif System.Workflow.ComponentModel.ParameterDeclaration WebPage = new
System.Workflow.ComponentModel.ParameterDeclaration();
InBlock.gif System.Workflow.ComponentModel.ParameterDeclaration PageData = new
System.Workflow.ComponentModel.ParameterDeclaration();
InBlock.gifthis.webTear1 = new
Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear();
InBlock.gif//

InBlock.gif
//
webTear1
InBlock.gif
//

InBlock.gif
this.webTear1.ID = "webTear1" ;
InBlock.gif activitybind1.ID = "/Workflow"
;
InBlock.gif activitybind1.Path = "webSite"
;
InBlock.gifthis.webTear1.PageFinished += new Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.PageFinishedEventHandler(this
.webTear1_PageFinished);
InBlock.gifthis
.webTear1.SetBinding(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.WebPageProperty, ((System.Workflow.ComponentModel.Bind)(activitybind1)));
InBlock.gif//

InBlock.gif
//
WebTearActivityWorkflow
InBlock.gif
//

InBlock.gif
this.Activities.Add(this .webTear1);
InBlock.gifthis.DynamicUpdateCondition = null
;
InBlock.gifthis.ID = "WebTearActivityWorkflow"
;
InBlock.gif WebPage.Direction =
System.Workflow.ComponentModel.ParameterDirection.In;
InBlock.gif WebPage.Name = "WebPage"
;
InBlock.gif WebPage.Type = typeof
(System.String);
InBlock.gif WebPage.Value = null
;
InBlock.gif PageData.Direction =
System.Workflow.ComponentModel.ParameterDirection.Out;
InBlock.gif PageData.Name = "PageData"
;
InBlock.gif PageData.Type = typeof
(System.String);
InBlock.gif PageData.Value = null
;
InBlock.gifthis
.Parameters.Add(WebPage);
InBlock.gifthis
.Parameters.Add(PageData);
InBlock.gifthis.Initialized += new System.EventHandler(this
.InitVars);
InBlock.gif
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private void InitVars(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gif webSite = this.Parameters["WebPage"
].Value.ToString();
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private void webTear1_PageFinished(object sender, PageFinishedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gifthis.Parameters["PageData"].Value =
e.Data;
ExpandedSubBlockEnd.gif }

ExpandedSubBlockEnd.gif }
ExpandedBlockEnd.gif}


创建宿主程序

这里的宿主程序是一个Winform程序,它有一个TextBox来输入要下载的url,当点击Go按钮,工作流开始运行,并执行WebTear活动开始下载网页。工作流运行完后,宿主程序从WorkflowCompleteEventArgs对象中获得网页数据,并把它显示在另一个TextBox中。以下代码演示了如何实现宿主程序(译者注:私自去掉了不重要的代码,要看完整的自个儿去msdn上找,呵呵)。

None.gif ……
None.gif
None.gifnamespace
Microsoft.Samples.Workflow.Quickstarts.CustomActivity
ExpandedBlockStart.gifContractedBlock.gifdot.gif
{
InBlock.gifpublic class
MainForm : Form
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gifprivate
System.Windows.Forms.Label addressCaption;
InBlock.gifprivate
System.Windows.Forms.TextBox address;
InBlock.gifprivate
System.Windows.Forms.TextBox data;
InBlock.gifprivate
System.Windows.Forms.Button goButton;
InBlock.gif
InBlock.gifprivate
WorkflowRuntime workflowRuntime;
InBlock.gif
InBlock.gifpublic
MainForm()
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gif InitializeComponent();
InBlock.gif
InBlock.gif workflowRuntime = new
WorkflowRuntime();
InBlock.gif workflowRuntime.StartRuntime();
InBlock.gif
InBlock.gif workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>
(workflowRuntime_WorkflowCompleted);
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gif// Retrieve the downloaded page data

InBlock.gif
if (data.InvokeRequired)
InBlock.gif data.Invoke(new EventHandler<WorkflowCompletedEventArgs>
(workflowRuntime_WorkflowCompleted), sender, e);
InBlock.gifelse

InBlock.gif data.Text = e.OutputParameters["PageData" ].ToString();
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif
private void goButton_Click(object sender, EventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gifdot.gif
{
InBlock.gif Type type = typeof
(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTearActivityWorkflow);
InBlock.gif
InBlock.gif//
Sending the data to the workflow.
InBlock.gif
// First create the required property set

InBlock.gif
Dictionary<string, object> properties = new Dictionary<string, object> ();
InBlock.gif properties.Add("WebPage"
, address.Text);
InBlock.gif properties.Add("PageData", ""
);
InBlock.gif
InBlock.gif workflowRuntime.StartWorkflow(type, properties);
ExpandedSubBlockEnd.gif }

InBlock.gif
InBlock.gif ……
ExpandedSubBlockEnd.gif }

ExpandedBlockEnd.gif}



本文转自高海东博客园博客,原文链接:http://www.cnblogs.com/ghd258/archive/2005/12/31/309165.html,如需转载请自行联系原作者
相关文章
|
消息中间件 Kafka Windows
Kafka Windows运行错误:创建消费者报错 consumer zookeeper is not a recognized option
Kafka Windows运行错误:创建消费者报错 consumer zookeeper is not a recognized option
469 0
Kafka Windows运行错误:创建消费者报错 consumer zookeeper is not a recognized option
|
PHP Windows
php windows多进程,php windows创建多进程,
php windows多进程,php windows创建多进程,
505 0
|
Linux 测试技术 iOS开发
【实测】windows下进程的创建和终止-python3
【实测】windows下进程的创建和终止-python3
|
Windows
技巧:Windows自定义运行命令
技巧:Windows自定义运行命令
156 0
技巧:Windows自定义运行命令
|
存储 安全 搜索推荐
微软发布 Windows 365:将 PC 置于云端,几分钟就能创建
微软发布 Windows 365:将 PC 置于云端,几分钟就能创建
166 0
微软发布 Windows 365:将 PC 置于云端,几分钟就能创建
|
Shell 开发工具 git
如何在Windows上使用Git创建一个可执行脚本?
长话短说,今天介绍如何在windows上使用Git上创建一个可执行的shell脚本。
如何在Windows上使用Git创建一个可执行脚本?
|
开发工具 Python Windows
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(三)
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(三)
141 0
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(三)
|
Python Windows
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(二)
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(二)
135 0
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(二)
|
Python Windows
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(一)
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(一)
191 0
【开发环境】Windows 安装 PyCharm 开发环境 ( 下载 PyCharm | 安装 PyCharm | 在 PyCharm 中创建 Python 工程 )(一)
|
C++ Windows
【Visual Studio】Visual Studio 2019 创建 Windows 控制台程序 ( 安装 ‘使用 C++ 的桌面开发‘ 组件 | 创建并运行 Windows 控制台程序 )(二)
【Visual Studio】Visual Studio 2019 创建 Windows 控制台程序 ( 安装 ‘使用 C++ 的桌面开发‘ 组件 | 创建并运行 Windows 控制台程序 )(二)
190 0
【Visual Studio】Visual Studio 2019 创建 Windows 控制台程序 ( 安装 ‘使用 C++ 的桌面开发‘ 组件 | 创建并运行 Windows 控制台程序 )(二)