KimhillZhang  

工作流代码给任务表单域赋值

上一节讲述了如何设计工作流的任务表单,以及如何让任务表单跟工作流的任务关联起来。在很多情况下,工作流代码需要访问任务表单中的域,给某个域赋值或者获取某个域的值。

工作流代码不能直接给表单域赋值,给表单域赋值必须借助于辅助数据源来进行。以下是添加辅助数据源的步骤。

Step1  新建ItemMetadata.xml文件。新建一个文本文件,改名为ItemMetadata.xml,添加以下内容。

      <z:row xmlns:z="#RowsetSchema"

         ows_comments="" />

以ows开头的属性是辅助数据源中的字段,工作流代码可以控制这些字段的值,按照需要可以添加多个字段,但是要注意字段命名的格式以ows_开头。

Step2  添加数据连接。选择"工具"菜单中的"数据连接"命令,如图1所示。

1 选择"数据连接"命令

Step3  在弹出的"数据连接"窗口中单击"添加"按钮,再在弹出的对话框中选择"新建连接""仅接收数据"单选按钮,如图2所示,单击"下一步"按钮。

2 添加数据连接

Step4  选择"XML文档"单选按钮,如图3所示,单击"下一步"按钮。选择Step1中新建的"ItemMetadata.xml"文件作为数据文件,如图4所示。

   

  3 选择"XML文档"接收数据               4选择"ItemMetadata.xml"文件

Step5  确认选中如图 5所示的单选按钮。输入数据连接名称为"ItemMetadata",单击"完成"按钮,如图 6所示。

     

数据连结向导                             输入数据连接的名称

添加好辅助数据源后,需要将辅助数据源中的属性和表单域默认值关联起来。工作流代码可以控制辅助数据源中字段的值,但在默认情况下,辅助数据源是不会显示到表单上的,一般设置表单域的默认值为辅助数据源中字段的值,这样表单加载的时候即可显示辅助数据源中的字段数据。假设要在任务表单显示的时候,审批意见框默认显示辅助数据源中ows_comments字段的值,操作步骤如下。

Step1  选择主数据源中的"comments"域,弹出如图 7所示的属性编辑窗口。

Step2  单击默认值区域中的编辑按钮,在"插入公式"窗口中单击"插入域或组"按钮,如图 8所示。

属性编辑窗口

单击"插入域或组"按钮

Step3  "选择域或组"窗口中,切换到ItemMetadata辅助数据源,选择"ows_comments"域,单击"确定"按钮,如图 9所示。

Step4  依次单击"确定"按钮,返回域或组属性编辑窗口,如图 10所示,单击"确定"按钮。

选择域

10   设置初始值

Step5  表单修改好后,需要重新发布表单到工作流项目所在的目录。最后修改工作流代码,来给辅助数据源中的ows_comments域赋值。修改createTaskMethodInvoking事件处理方法如下。

private void createTask1_MethodInvoking(object sender, EventArgs e)

        {

            this.task1Id = Guid.NewGuid();

            this.task1Properties.Title = "文档审批";

            this.task1Properties.AssignedTo = "codeart\\user1";

            this.task1Properties.TaskType = 0; //设置任务使用第一个任务表单

            //设置infopath表单中的comments字段值

            this.task1Properties.ExtendedProperties["comments"] = "请在此输入您的审批意见";

             //分配任务编辑权限

            this.specialPermissions1.Add(this.task1Properties.AssignedTo,

SPRoleType.Contributor);

        }

通过SPWorkflowTaskProperties类的ExtendedProperties属性可控制辅助数据源的值。

工作流代码获取任务表单域的值

在以上几节的示例中,任务提交完成后工作流代码并没有处理,在本章的文档审批示例流程中,审批人批准之后,文档才应该正式发布,若没有批准则不能发布。

SharePoint文档库本身支持内容审批功能,启用内容审批功能后,文档新建或上传后处于草稿状态,只有当有权限的用户审批之后,文档才能被普通用户浏览。

通过文档库设置中的版本控制设置可以启动内容审批功能,如图10所示。在"提交的项目是否需要内容审批"选项中选择"是"单选按钮,在"哪些用户可查看此文档库中的草稿项目"选项中选择"仅限可批准项目的用户(以及该项目的作者)"单选按钮可以查看草稿项目。

10 启用内容审批

下面修改工作流代码,实现当用户操作任务表单时,选择"批准"则将文档的审批状态改为"已批准",选择"拒绝"则将文档的状态改为"已拒绝"。

双击工作流设计器上的"onTaskChange"活动,在自动生成的Invoked事件处理函数中添加如下代码。

        private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)

        {

            //获取到任务表单中的approval字段

            bool approval = Convert.ToBoolean(this.task1Properties.

ExtendedProperties["approval"]);

            //获取到任务表单中的comments字段

            string comments = "" + this.task1Properties.ExtendedProperties["comments"];

            SPModerationStatusType approvalState = approval ? SPModerationStatusType.

Approved : SPModerationStatusType.Denied;

            SPListItem item = this.workflowProperties.Item;

            item["_ModerationStatus"] = (int)approvalState; //设置内容审批状态

            item["_ModerationComments"] = comments;     //设置内容审批批注

            item.Update();

        }

可以通过SPWorkflowTaskProperties类的ExtendedProperties属性获取表单域的数据。以上代码按照approval域的值设置列表项的_ModerationStatus字段为相应值,并把comments表单域的值赋给列表项的_ModerationComments字段。

工作流模板的关联表单

工作流模板的关联表单是当把一个工作流模板和某个列表(或文档库)关联起来时调用的表单,一般用来实现一些流程相关的配置。

在流程代码中,可以通过workflowProperties字段的AssociationData属性获取到关联表单的数据。AssociationData放置的是关联表单的XML格式的数据。

下面给文档审批流程示例添加一个功能为管理员将文档审批工作流模板附加到某个文档库时可以指定审批人,并且可以指定一些人员,发送提醒邮件。

1.设计表单模板

Step1  新建表单模板,保存为"AssociationForm.xsn"。

Step2  通过属性菜单,把数据源根节点的名称由"myFields"修改为"ConfigurationData"

Step3  添加人员选择控件。在"设计任务"的"插入控件"面板单击"添加或删除自定义控件"链接,如图12所示。

12  "插入控件"面板

在"添加或删除自定义控件"窗口中单击"添加"按钮,在弹出的窗口中选择"ActiveX控件"单选按钮,如图13所示。选择"Contact Selector"控件,如图14所示。

13 选择控件类型

14 选择控件

选择"不包括.cab文件"单选按钮,如图15所示。指定绑定属性为"Value",如图16所示。指定数据类型为"域或组",如图17所示。

15 指定安装选项

16 指定绑定类型

17 指定控件数据类型

Step4  配置人员选择控件的数据源。人员选择控件必须绑定到格式固定的组,首先添加一个名为"ApprovalUser"的组,然后在ApprovalUser组下添加一个名为"Person"的可重复组,如图18所示。在Person组下分别添加"DisplayName""AccountId""AccountType"3个文本域,最终数据源结构如图19所示。

18 添加Person

19 数据源结构

Step5  将Contract Selector拖放到表单上,利用右键菜单的"更改绑定"命令绑定到ApprovalUser组,如图20所示。

20 更改绑定

Step6  按照Step4Step5的操作,添加一个"MailTo"组,并添加"MailSubject""MailBody"两个文本字段,如图21所示。

21数据源

Step7  按照如图22所示的向导完成表单设计,完成后的效果如图23所示。

22 表单效果

Step8  发布表单。确认表单的安全级别为"完全信息",将表单发布到项目所在目录,发布文件名为"AssociationForm.xsn"

2.修改配置文件

接下来需要修改配置文件,将AssociationForm.xsn跟工作流模板进行关联。

Step1  修改feature.xml。在ElementManifests节点下添加如下代码。

<ElementFile Location="AssociationForm.xsn" />

Step2  修改workflow.xml文件。在Workflow节点下添加如下属性。

AssociationUrl="_layouts/CstWrkflIP.aspx"

MetaData节点下添加如下属性。

<Association_FormURN>urn:schemas-microsoft-com:office:infopath:AssociationForm:

-myXSD-2008-10-04T07-45-17</Association_FormURN>

FormURN可以通过infopath属性窗口获得。

3.修改工作流代码

下面修改工作流代码,在创建任务的时候从关联表单数据中获取审批用户,并给相应的用户发送邮件。关联表单数据的访问有两种方法。

(1)直接通过XML对象模型访问,示例代码如下。

private void createTask1_MethodInvoking(object sender, EventArgs e)

        {

            this.task1Id = Guid.NewGuid();

            this.task1Properties.Title = "文档审批";

            XmlDocument doc = new XmlDocument();

            //加载关联表单的XML数据

            doc.LoadXml(workflowProperties. AssociationData);

           //设置名称空间

            XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

            nsmgr.AddNamespace("my", doc.DocumentElement.Attributes["xmlns:my"].Value);

            //查询审批人账号

            string aprovalUserAccount =

                   doc.DocumentElement.SelectSingleNode("my:ApprovalUser/my:Person/my:

                   AccountId", nsmgr).InnerText;

           //将任务分配给审批人

            this.task1Properties.AssignedTo = aprovalUserAccount;

           this.task1Properties.TaskType = 0;

           this.task1Properties.ExtendedProperties["comments"] = "请在此输入您的审批意见";

           this.specialPermissions1.Add(this.task1Properties.AssignedTo,

SPRoleType.Contributor);

        }

以上代码采用XmlDocument从关联表单数据中获取到审批人账号,然后分配审批任务。

(2)由表单的schema生成对应的类,直接将关联表单数据反序列化为这个类,通过这个类来访问。 

Step1  通过InfoPath的文件菜单,将表单另存为源文件,如图24所示。

24 另存为源文件

Step2  打开Visual Studio 2008命令提示。

(选择"开始"菜单中的"Microsoft Visual Studio 2008"→"Visual Studio Tools"→"Visual Studio 2008 Command Prompt")

Step3  在命令行窗体中使用cd命令转向Step1中保存的源文件路径。

Step4  输入"xsd myschema.xsd/c"命令,并到源文件路径找到生成的myschema.cs文件,改名为"ConfigurationData.cs",将ConfigurationData.cs复制到工作流项目中。为了方便关联表单数据的访问,在工作流中声明以下属性。

private ConfigurationData _ConfigurationData;

        ///<summary>

        ///配置数据

        ///</summary>

        public ConfigurationData ConfigurationData

        {

            get

            {

                if (_ConfigurationData == null)

                {  //将关联表单数据反序列化为相应的对象

                    XmlSerializer serializer = new XmlSerializer(typeof(ConfigurationData));

                    XmlTextReader reader = new XmlTextReader(new System.IO.StringReader(

this.workflowProperties.AssociationData));

                    _ConfigurationData = (ConfigurationData)serializer.Deserialize(

reader);

                }

                return _ConfigurationData;

            }

        }

相应的createTask1_MethodInvoking方法可以修改如下。

        private void createTask1_MethodInvoking(object sender, EventArgs e)

        {

            this.task1Id = Guid.NewGuid();

            this.task1Properties.Title = "文档审批";

            //通过反序列化后的类获取审批人账号

            this.task1Properties.AssignedTo = this.ConfigurationData.ApprovalUser[0].

AccountId;

           this.task1Properties.TaskType = 0;

           this.task1Properties.ExtendedProperties["comments"] = "请在此输入您的审批意见";

            this.specialPermissions1.Add(this.task1Properties.AssignedTo,

SPRoleType.Contributor);

        }

邮件发送逻辑的实现需要采用sendEmail活动实现,并且收件人是非必填字段,需要采用IfElse活动来判断是否需要执行sendEmail活动。

Step1  拖曳IfElse活动到工作流设计器中,如图25所示。

25 添加IfElse活动

Step2  指定ifElseBranchActivity1的条件类型为"Code Condition",条件函数为"NeedSendMail",双击"Condition"输入框,如图26所示。

26 指定Condition

Step3  在自动生成的Condition方法中添加如下代码。

///<summary>

        ///判断是否需要发送邮件

        ///</summary>

        ///<param name="sender"></param>

        ///<param name="e"></param>

        private void NeedSendMail(object sender, ConditionalEventArgs e)

        {  //如果配置了邮件地址则需要发送邮件

            e.Result = this.ConfigurationData.MailTo != null &&

                this.ConfigurationData.MailTo.Length > 0 ;

        }

Step4  拖曳sendEmail活动到ifElseBranchActivity1,并设置其CorrelationTokentask1Token,如图27所示。

27  添加sendEmail活动

Step5  处理sendEmail活动的MethodInvoking方法,代码如下。

private void sendEmail1_MethodInvoking(object sender, EventArgs e)

        {

            string to = "";

            foreach (Person p in this.ConfigurationData.MailTo)

            {

                Contact contact = Contact.FromName(p.AccountId,

this.workflowProperties.Web);

                if (to != "") to = ";";

                to += contact.EmailAddress;

            }

            this.sendEmail1.To = to;

            this.sendEmail1.Subject = this.ConfigurationData.MailSubject;

            this.sendEmail1.Body = this.ConfigurationData.MailBody;

        }

以上代码遍历配置类中的账号,采用Contact.FromName方法转换成Contact对象,通过Contact对象的EmailAddress取到用户的邮件。

4.测试关联表单

采用Visual Studio 2008部署工作流时,关联表单不会出现,要测试关联表单,必须手工将工作流模板关联到文档库或列表。部署工作流后,采用以下步骤测试关联表单。

Step1  进入工作流设置页面,单击"添加工作流"链接,如图28所示。

28 工作流设置

Step2  在添加或更改工作流页面,选择要附加的工作流(CodeArt.WorkflowDemo1),输入工作流名称,如图29所示,单击"下一步"按钮。

29 添加工作流

Step3  配置关联表单。在关联表单设置页面(如图30所示),输入相关信息,单击"提交"按钮完成工作流关联操作。

30 关联表单


转载:http://book.csdn.net/bookfiles/936/10093629438.shtml

posted on 2009-07-24 11:07  KimhillZhang  阅读(1077)  评论(1编辑  收藏  举报