您的位置:首页 > 其它

[转帖]Windows Workflow Foundation之旅(五)——指南3(创建自定义活动)

2007-06-25 15:02 627 查看
Windows Workflow Foundation之旅(五)——指南3(创建自定义活动)
翻译自: ms-help://MS.WinWF.v1.EN/WinWF_GettingStarted/html/8b6344bc-c879-41c5-babf-74e91c34d281.htm

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

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

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

创建WebTearActivity类

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


using System;


using System.ComponentModel;


using System.Workflow.ComponentModel;


using System.Workflow.ComponentModel.Design;


using System.Workflow.ComponentModel.Compiler;




namespace Microsoft.Samples.Workflow.Quickstarts.CustomActivity






{


[ToolboxItemAttribute(typeof(ActivityToolboxItem))]


public class WebTear : System.Workflow.ComponentModel.Activity






{


}


}

定义活动属性

自定义活动属性的定义和WinForm控件属性的定义类似。当你定义一个自定义活动的属性时,使用DependencyProperty来存储属性的属性。这能让各种不同类型的属性都能一致地有效地工作。在实际定义属性时,你可能还会用到DependencyProperty类中的方法,所以,不要把这个字段定义成private。
活动中的一个属性可以应用许多不同的特性。这些特性通常都是用来支持WWF设计器的工作的。我们的这个属性应用了一下的特性:
1. CategoryAttribute:在设计器的属性窗口中,这个属性位于那个分类下。
2. DescriptionAttribute:设计器属性窗口中显示的属性描述。
3. BrowsableAttribute:这是一个布尔值,指示了是否在属性窗口中显示这个属性。
4. ValidationVisibilityAttribute:指定了如何验证属性的值。验证选项包括:可选Optional、必需Required、隐藏Hidden。
5. DesignerSerializationVisibilityAttribute:指定了是否和如何序列化这个属性。选项包括:可见Visible、隐藏Hidden、内容Content。
以下的代码示例了如何定义WebPage属性。


public static DependencyProperty WebPageProperty =


DependencyProperty.Register("WebPage", typeof(System.String), typeof (Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear ) );




[DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]


[ValidationVisibilityAttribute(ValidationVisibility.Optional)]


[BrowsableAttribute(true)]


[DescriptionAttribute("Web page to download")]


[CategoryAttribute("WebTear Property")]


public string WebPage






{


get






{


return ((string)(base.GetValue(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.WebPageProperty)));


}


set






{


base.SetValue(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.WebPageProperty, value);


}


}

重载Execute方法

当你创建了一个自定义活动,运行时,工作流引擎会调用活动的Execute方法来执行活动实际的操作。这个方法是在基类中定义的,但你可以重载这个方法,以适应你的活动的功能。
WebTear活动会在Execute方法中下载请求的网页,并在下载完成后引发一个事件,将页面数据发回工作流。我们需要定义一个PageFinishedEventArgs类用于事件参数,这个类中有一个Data字段用来存放网页数据。这些数据会在之后被工作流中的事件处理函数访问到。一旦数据下载完毕,Execute方法返回一个Status.Closed枚举值,来通知工作流引擎活动已经完成执行了。
一下的代码演示了如何定义PageFinishedEventArgs类


public class PageFinishedEventArgs






{


private string data;




public PageFinishedEventArgs( string data )






{


this.data = data;


}




public string Data






{




get

{ return data; }


}


}

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


public delegate void PageFinishedEventHandler( object sender, PageFinishedEventArgs e );


public event PageFinishedEventHandler PageFinished;




protected override Status Execute(ActivityExecutionContext context)






{


System.Net.WebClient client = new System.Net.WebClient();


string pageData;




try






{


// Download the web page data


pageData = client.DownloadString(WebPage);


}


catch (Exception e)






{


pageData = e.Message;


}




// Raise the PageFinished event back to the host


PageFinished(null, new PageFinishedEventArgs(pageData));




// Notifiy the runtime that the activity has finished


return Status.Closed;


}

为WebTear活动创建顺序工作流。

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


using System;


using System.ComponentModel;


using System.Workflow.ComponentModel;


using System.Workflow.ComponentModel.Design;


using System.Workflow.ComponentModel.Compiler;


using System.Workflow.Activities;




namespace Microsoft.Samples.Workflow.Quickstarts.CustomActivity






{


public sealed partial class WebTearActivityWorkflow : SequentialWorkflow






{


private string webSite;


private WebTear webTear1;




public WebTearActivityWorkflow()






{


InitializeComponent();


}




private void InitializeComponent()






{


System.Workflow.ComponentModel.ActivityBind activitybind1 = new System.Workflow.ComponentModel.ActivityBind();


System.Workflow.ComponentModel.ParameterDeclaration WebPage = new System.Workflow.ComponentModel.ParameterDeclaration();


System.Workflow.ComponentModel.ParameterDeclaration PageData = new System.Workflow.ComponentModel.ParameterDeclaration();


this.webTear1 = new Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear();


//


// webTear1


//


this.webTear1.ID = "webTear1";


activitybind1.ID = "/Workflow";


activitybind1.Path = "webSite";


this.webTear1.PageFinished += new Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.PageFinishedEventHandler(this.webTear1_PageFinished);


this.webTear1.SetBinding(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTear.WebPageProperty, ((System.Workflow.ComponentModel.Bind)(activitybind1)));


//


// WebTearActivityWorkflow


//


this.Activities.Add(this.webTear1);


this.DynamicUpdateCondition = null;


this.ID = "WebTearActivityWorkflow";


WebPage.Direction = System.Workflow.ComponentModel.ParameterDirection.In;


WebPage.Name = "WebPage";


WebPage.Type = typeof(System.String);


WebPage.Value = null;


PageData.Direction = System.Workflow.ComponentModel.ParameterDirection.Out;


PageData.Name = "PageData";


PageData.Type = typeof(System.String);


PageData.Value = null;


this.Parameters.Add(WebPage);


this.Parameters.Add(PageData);


this.Initialized += new System.EventHandler(this.InitVars);




}




private void InitVars(object sender, EventArgs e)






{


webSite = this.Parameters["WebPage"].Value.ToString();


}




private void webTear1_PageFinished(object sender, PageFinishedEventArgs e)






{


this.Parameters["PageData"].Value = e.Data;


}


}


}

创建宿主程序

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


……




namespace Microsoft.Samples.Workflow.Quickstarts.CustomActivity






{


public class MainForm : Form






{


private System.Windows.Forms.Label addressCaption;


private System.Windows.Forms.TextBox address;


private System.Windows.Forms.TextBox data;


private System.Windows.Forms.Button goButton;




private WorkflowRuntime workflowRuntime;




public MainForm()






{


InitializeComponent();




workflowRuntime = new WorkflowRuntime();


workflowRuntime.StartRuntime();




workflowRuntime.WorkflowCompleted += new EventHandler<WorkflowCompletedEventArgs>(workflowRuntime_WorkflowCompleted);


}




void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)






{


// Retrieve the downloaded page data


if (data.InvokeRequired)


data.Invoke(new EventHandler<WorkflowCompletedEventArgs>(workflowRuntime_WorkflowCompleted), sender, e);


else


data.Text = e.OutputParameters["PageData"].ToString();


}




private void goButton_Click(object sender, EventArgs e)






{


Type type = typeof(Microsoft.Samples.Workflow.Quickstarts.CustomActivity.WebTearActivityWorkflow);




// Sending the data to the workflow.


// First create the required property set


Dictionary<string, object> properties = new Dictionary<string, object>();


properties.Add("WebPage", address.Text);


properties.Add("PageData", "");




workflowRuntime.StartWorkflow(type, properties);


}




……


}


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