一步一步学习sharepoint2010 workflow 系列第三部分:自定义SharePoint代码工作流 第10章 工作流和任务处理(Workflows and task processes)

本章涵盖
使用任务相关工作流活动

构建自定义任务编辑表单

 

  在第4章,SharePoint Designer工作流提供了任务处理能力。Visual Studio提供了类似的任务处理能力为它的工作流。Task-related 活动使Visual Studio工作流能创建任务,删除任务,和完成任务。他们也有事件活动,你的工作流能使用去人交互例如任务编辑和删除。通过放入这些活动去使用,你可以创建和分配任务给用户,并且任务等待完成。

Visual Studio 还支持完整自定义任务编辑表单和自定义InfoPath表单。这些表单能很容易的集成到你的Visual Studio工作流去支持复杂的表单要求或者使你的最终用户很直观的使用。当分配编辑任务,默认情况下,认为开箱即用任务编辑表单和这个表单可能不足。例如,开箱即用表单包含许多字段你可能不需要最终用户去编辑。这些额外数据可能会给最终用户造成混乱,建立一个自定义InfoPath表单是可取的。 

 10.1 使用task-related 活动

 除了在SharePoint Designer中创建工作流,Visual Studio工作流提供了类似任务处理的机会。Visual Studio中的多个SharePoint活动帮助管理工作流中的任务。你可以使用这些活动在你的Visual Studio工作流去创建,删除和更新任务。表10.1显示任务关联活动清单。在这一章,并不覆盖表10.1所有的活动,我们将介绍最常用的活动,如创建和删除任务和事件交互类似任务修改和删除。

表10.1 

 

 
现在你有了所有可用任务活动的清单,让我们建立一个例子去使用它们。这个例子你将去通过类似Capital Expenditure请求工作流,之前你建立在SharePoint Designer,现在,你将建立它在Visual Studio。这将有助于比较两个工作流工具。它们不需要创建一个新的请求列表,你将添加第二个工作流到节4.2的列表。开始时,创建一个新的Visual Studio 顺序工作流项目标题为CapitalExpenditureRequests。在项目创建向导,输入包含你的capital expenditure请求列表的网站网址,创建一个新的列表工作流,名字为Expenditure Requests Approval—VS.Last,关联新的工作流到capital expenditure request 列表。

第4章示例依赖  

注意这个例子是在节4.2建立的,那个节介绍你通过SharePoint Designer建立一个Capital Expenditure Request工作流。如果你不希望回到第4章,创建一个新的自定义列表叫Capital Expenditure Request。添加两个列到列表,RequestDescription是多行文本字段和Dollar Amount是货币类型。有了这个通用的列表你将赶上进度。

 

如果你记得,在SharePoint Designer请求示例你有两个动作去检查工作流项更新或者删除。只要符合一种情况,你希望工作流停止处理。去设置相同的功能从你的Visual Studio工作流,你可以使用EventHandlingScope活动搭配OnTaskDeleted和OnWorkflowItemChanged活动。EventHandlingScope活动允许你去在活动范围内的事件触发交互。你将放入你工作流业务逻辑核心到这个活动。所以每次一个任务删除,例如,你的EventHandlingScope活动将捕捉事件并执行代码。按照表10.2的步骤去配置这些事件。 

 表10.2

 

 

 

 

 图10.1

 

 现在你的工作流监听请求更新、取消工作流和删除任务如果这些发生。如果工作流等待任务的提交和任务被删除,你想去确认你的工作流不在一个孤立的状态。在第二个EventDriven活动添加一个新的OnTaskDeleted。
添加和配置SetState和terminate活动像你的第一个EventDriven活动。Correlation toekn为SetState活动需要设置为workflowToekn。有某个点在加入DeleteTask活动,因为通过这个点,它将被删除。之后,你的第二个EventDriven活动看起来像图10.2。

 图10.2

 现在修改和删除事件链接起来,现在去添加主要业务逻辑到你的工作流。像SharePoint Designer示例,当工作流启动你想要的任务创建。任务创建之后,你想去等待批准人批准或者拒绝请求。批准或者拒绝之后,你设置工作流状态到相应状态。让我们开始创建任务,并等待它的审批。按照表10.3的步骤去配置工作流部分。

TaskId属性和OnTaskDeleted活动的CorrelationToken  

确保OnTaskDeleted活动上的TaskId属性是设置为和DeleteTask活动相同。所有的这些在capital expenditure请求工作流上的活动是工作相同的任务,他们的TaskId属性也应该是相同的。请注意,correlation Token必须设置为TaskToken因为这是用于DeleteTask活动的token。

 

表10.3

 

 

Listing 10.1 createTask1_MethodInvoking 

 

private void createTask1_MethodInvoking(object sender, EventArgs e)

{
TaskProperties.Title =
onWorkflowActivated1.WorkflowProperties.Item.Title;
TaskProperties.Description =
onWorkflowActivated1.WorkflowProperties.
Item["Request Description"].ToString();
TaskProperties.AssignedTo = "philsdevdomain\\pwicklund";

} 

 

表10.3 续

 

 

Listing 10.2 WhileTaskNotComplete 

bool taskComplete = false;

private void WhileTaskNotComplete(object sender, ConditionalEventArgs e)
{
if (taskComplete)
e.Result = false// similar to while(0)
else
e.Result = true// similar to while(1)

} 

 

续表10.3

 

 

Listing 10.3 onTaskChanged1_Invoked 

private Guid statusColumnId =

new Guid("{c15b34c3-ce7d-490a-b133-3f4de8801b76}");
private string status = "";
private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
{
status = AfterProperties.ExtendedProperties [statusColumnId].ToString();
if (status == "Not Started")
taskComplete = false;
else
taskComplete = true;

} 

 

ExtendedProperties属性如何工作

TaskProperties属性包含许多任务公共字段如Title,DueDate,和Description对于一些默认列像Status和任何自定义列,ExtendedProperties必须使用。ExtendedProperties是一个哈希包含默认列如Status,以及任何自定义列,或者通过一个内容类型。有趣的事情是默认列是输入在哈希通过一个唯一的ID,他们的GUID,而自定义列是通过他们的列名进入的。 

 

  图10.3显示如何获取字段ID通过PowerShell如果你想去检索默认列从ExtendedProperties属性的哈希。 

 图10.3

 有了这些步骤,你的While活动将停止循环,当Status列改变到Not Started。现在你添加ifEsle活动去确定如何设置工作流状态。如果Status 在任务中是设置为Approved。设置工作流Status为Approved。如果任务的状态是为Deferred,设置工作流状态为Deferred,以此类推。

注意:默认,Approved和Reject状态不在Status中。在任务列表,编辑Status列,并输入状态,类似图10.4

  10.4

通过表10.4 

配置IfElse活动,以确定Status是否Approved或Deferred

 

 

 

  此时,你的工作流已经接近完成。剩下的是填写SetState活动。在做这个之前,先确认你的工作流设计界面看起来像图10.5。

 图10.5

 

 为了和我们之前创建的SharePoint Designer工作流保持一致,我们需要去添加一些SendEmail活动去发送通知。这个活动涵盖在第八章,我们这里将跳过。

第一步设置你的自定义工作流Statuses在工作流的Elements.xml文件中的定义。任何的自定义状态需要在这个XML文件中的MetaData元素中定义。Status外面的子元素我们叫做ExtendedStatusColumnValues,每个状态都在一个StatusColumnValue标签中。打开工作流的Elements.xml并定义你的扩展状态值,看起来像图10.6。 

 图10.6

 

 每一个SetState活动有一个属性叫State。这是一个整数值确定工作流状态。这里有15个状态,你可以将这些属性设置1到15,你将设置你的工作流状态。表10.5显示这些状态的当前值对象模型。

表10.5

 

 

要设置工作流到你的自定义状态的某一个,你需要去设置它为16或者更高。例如,如果你设置它为16,你需要设置工作流状态为Approved。如果你设置它为19,工作流状态需要设置为Canceled。而不是硬编码一个值,最好的做法是通过代码。通过代码,你可以使用SPWorkflowStatus.Max属性。这将保护你如果微软不断变化Max从15到16.要做这一点,配置你的SetState处理类似列表10.4。 

Listing 10.4 Handlers for the SetState activities

 enum CustomStates

{
Approved = 0,
Rejected,
Deferred,
Canceled
};
private void setCanceledState_MethodInvoking(object sender, EventArgs e)
{
((SetState)sender).State = (Int32)SPWorkflowStatus.Max +
(Int32)CustomStates.Canceled;
}
private void setApprovedState_MethodInvoking(object sender, EventArgs e)
{
((SetState)sender).State = (Int32)SPWorkflowStatus.Max +
(Int32)CustomStates.Approved;
}
private void setDeferredState_MethodInvoking(object sender, EventArgs e)
{
((SetState)sender).State = (Int32)SPWorkflowStatus.Max +
(Int32)CustomStates.Deferred;
}
private void setRejectedState_MethodInvoking(object sender, EventArgs e)
{
((SetState)sender).State = (Int32)SPWorkflowStatus.Max +
(Int32)CustomStates.Rejected;
}

 

  正如你看到的,你使用了枚举去设置你的自定义状态证书。然后在每个处理,你添加Max值到你的枚举整数值,计算状态。

你输入代码之后,生成你的项目并部署到SharePoint,之后,创建一个新的Expenditure request并运行这个新的工作流。你应该注意到工作流InProgress状态,一个新的任务创建在任务列表。然后在Capital Expenditure Request列表。Visual Studio工作流状态列应该有相应的状态。
(图10.7)

  10.7

 

 

 10.2  自定义任务编辑表单(Custom task edit forms)

你的Capital Expenditure Request工作流的核心已完成,但是有个问题一直存在。任务编辑表单审批者使用不直观。只能编辑Status列。这将很容易让审批者失去自己应该做的轨迹。 

表单服务器依赖  

本节规定SharePoint服务器版本。SharePoint Foundation不允许Infopath表单部署到表单服务器。

 

解决方案包括创建一个自定义InfoPath任务编辑表单。这个自定义表单将有请求的标题、描述和三个按钮:一个按钮去审批,推迟和拒绝表单。这个自定义InfoPath表单(图10.8)更直观的处理开支的请求。

 图10.8

 

在这一点上,你可能想,“为什么不自定义像第8章的开箱即用表单".虽然这是一个选项,大多数工作流是可重用的在他们被部署到更大的区域。而自定义开箱即用任务编辑表单需要一次又一次的建立,自定义表单你将建立它一次。

 跳到Visual Studio项目之前,你需要做一些指定的事情为这个InfoPath表单工作。注意在图10.8两个主要需求,显示capital expenditure request titile和description,显示三个按钮,每个接受的状态。

由于在设计时,InfoPath不知道关联列表,你不能直接在表单上添加SharePoint数据。SharePoint自定发送表单项数据到Infopath表单当表单加载。所有你需要去做的是告诉InfoPath表单要获取什么数据。要做到这点,你需要去设置一个二级数据源指向到一个XML文件标题为ItemsMetadata.xml。按照表10.6的步骤设置。 

表10.6

 

 

当你的二级数据源创建,你可以添加控件到表单上读取数据。添加两个新控件到表单上,一个叫Title,另一个叫Description。对于Title的文本框,右击并选择更改绑定。选择ItemMetadata从数据源下拉列表,选择ows_Title字段。同样的事情做Description,除了选择的是ows_ Body字段。有了这两个文本康到位,当你的表单加载,它将拉出title和description数据,并寄放他们到这些字段。这将帮助审批者知道他们是否应该审批请求或者不审批。最后,配置三个按钮。然后,你将可以准备去发布。按照表10.7的步骤配置提交按钮。 

 表10.7

 

 

 

你已经准备好发布你的表单。保存表单并发布它到网络位置。当你发布时,确保安全级别设置为域。  

现在,让我们参与这个发布表单到你的Visual Studio工作流。对于更多的详细演练,请参见9.3节。按照表10.8的步骤去告诉工作流去使用你的自定义表单,而不是开箱即用的表单。

 表10.8

 

 

 

 图10.9

TaskProperties.TaskType  

TaskType属性让你创建多种类型的任务,并且能每个类型的任务关联不同的表单。注意工作流的Elements.xml文件中的Task0_FormURN元素的零。零在元素名相对应任务的TaskType属性。TaskType属性设置为零去通知工作流使用表单零当任务被编辑时。 这是很有帮助的当你创建两个任务,一个是正常的审批者,另外一个是CEO。CEO的需要看到不同的表单当他们审批请求。在这种情况下,正常审批者能获取任务类型零,CEO能获取另一个任务类型,他们都有自己的FormURN在elements.xml。

 

  在你部署之前,你需要去做之后一件事情-更新你的OnTaskChanged活动。如果你记得,改活动是查找当前任务的Status列。现在,在你的自定义任务编辑表单,你不在去查找Status列,而是在InfoPath表单数据的ApprovalStatus字段当这个表单提交。进入OnTaskChanged事件处理,确认代码是引用ApprovalStatus列如列表10.5

 

Listing 10.5 onTaskChanged1_Invoked 

private string status = "";

private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs
e)
{
status = AfterProperties.ExtendedProperties
["ApprovalStatus"].ToString();

} 

重要的是注意,一个自定义任务编辑表单,你的任务不能被修改如果它没有提交。这意味着你不需要While活动。在此之前,有人可以轻松的更改任务的Title列,和永远不变的Status列。随意移动OnTaskChange活动到While活动外,并直接后面放置CreateTask活动。然后,你可以删除While活动。  

你终于准备测试。生成并部署Visual Studio解决方案。然后创建一个新的Capital Expenditure Request,然后启动工作流。点击任务,你应该看到你的自定义InfoPath任务编辑表单(图10.10)。在这个表单中,你将发现Title和Description,之后你单击三个按钮之一,工作流将完成,它的状态将被更新。
10.10

 

 

本章完 

 

本人声明

 
  本博客内的文字和图片除标明出处和转贴的外,均系本人原创作品,如转载或使用,不是用于盈利目的,尽请使用,但请注明引自这里和作者的名字;有商业用途的,请与本人联系,协商后再作使用,否则我将采取法律手段维护自己的利益。谢谢合作。meiweijun@163.com

 

posted on 2011-10-18 13:56  梅卫军  阅读(1554)  评论(0编辑  收藏  举报