上篇文章【QuickFlowDesigner教程(1)入门-快速开发可循环流程】讲述了如何快速配置一个审批流程,利用QuickFlow默认的审批界面进行流转,如果客户对界面要较高要求,就需要我们自定义页面了。

QuickFlow支持两种页面定制模式:

1)采用ListForm,ListForm是QuickFlow内置的一套表单框架,提供了一系列控件来组成工作流表单

2)采用标准的aspx.net页面,调用QuickFlow的API,因为QuickFlow是基于SharePoint工作流的,所以自定义的aspx表单直接调用SharePoint的API来驱动流程也是可以的。

本节我们先看看采用ListForm如何快速定义工作流表单。

先回顾下上一节的流程逻辑:

image

这个流程需要四种表单:

1)提交表单,提交人采用这个表单填写数据,启动流程

2)审批时的表单,审批人使用这个表单审批,可以输入审批意见,申请内容应该是只读的

3)打回时提交人修改的表单,申请内容应该是可以编辑的

4)数据查看表单

--------------------------------------------------------

Step1)首先创建一个网站项目,添加对QuickFlow.dll和QuickFlow.UI.dll的引用,

这两个dll哪里来呢?将安装包中的QuickFlow.wsp改名为QuickFlow.cab,然后就可以解压,你就看到这两个dll了。

Step2)创建DataView控件和DataEdit控件

在这个流程需要的四个表单中,申请数据表单是重复的,它只表现为两种形式:编辑状态或查看状态,为了代码复用,我们将这两种形式分别做成两个用户控件。

DataEdit.ascx代码如下:

<%@ Control Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="QuickFlow.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628"
    Namespace="QuickFlow.UI.Controls" TagPrefix="QFC" %>
<%@ Register Assembly="QuickFlow.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628"
    Namespace="QuickFlow.UI.ListForm" TagPrefix="QFL" %>
<table width="735" border="0" align="center" cellpadding="0" cellspacing="0" class="table_stroke">
    <tr>
        <td class="form-title">
            <table width="100%" border="0" cellspacing="0" cellpadding="0">
                <tr>
                    <td height="25" class="form-title_font">
                        QuickFlowDesigner 自定义表单示例
                    </td>
                </tr>
            </table>
        </td>
    </tr>
    <tr>
        <td align="right" class="form-title2">
        </td>
    </tr>
    <tr>
        <td>
            <table width="98%" border="0" cellpadding="2" cellspacing="0" class="table_stroke1">
                <tr>
                    <td class="form-label" width="200px">
                        标题
                    </td>
                    <td class="form-body">
                        <QFL:FormField ID="FormField3" runat="server" FieldName="Title">
                        </QFL:FormField>
                    </td>
                </tr>
                <tr>
                    <td class="form-label">
                        申请内容
                    </td>
                    <td class="form-body">
                        <QFL:FormField ID="FormField4" runat="server" FieldName="申请内容">
                        </QFL:FormField>
                    </td>
                </tr>
                <tr>
                    <td class="form-label">
                        申请理由
                    </td>
                    <td class="form-body">
                        <QFL:FormField ID="FormField5" runat="server" FieldName="申请理由">
                        </QFL:FormField>
                    </td>
                </tr>
                <tr>
                    <td class="form-label">
                        相关附件
                    </td>
                    <td class="form-body">
                        <QFL:FormAttachments ID="FormAttachments1" runat="server">
                        </QFL:FormAttachments>
                    </td>
                </tr>
                <tr>
                    <td class="form-body" colspan="2">
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

DataEdit控件主要使用了FormField来展现列表字段。

FormField内部采用SharePoint的字段控件来展现,通过控制列表的栏类型,即可控制FormField的展现形式。你也可以扩展SharePoint的栏类型,即可扩展FormField的类型。 

DataView控件代码跟DataEdit基本一样,只是将每个控件的ControlMode改成Display,如下:

<tr>
                            <td class="form-label" width="200px">
                                标题
                            </td>
                            <td class="form-body">
                                <QFL:FormField ID="FormField3" ControlMode="Display" runat="server" FieldName="Title">
                                </QFL:FormField>
                            </td>
 </tr>
 
Step3)创建提交页面-NewForm.aspx,先看代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="NewForm.aspx.cs" Inherits="QuickFlowExample_DesignerAndCustomForm_NewForm" %>
<%@ Register Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Namespace="Microsoft.SharePoint.WebControls" TagPrefix="SharePoint" %>
<%@ Register Assembly="QuickFlow.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628"
    Namespace="QuickFlow.UI.Controls" TagPrefix="QFC" %>
<%@ Register Assembly="QuickFlow.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628"
    Namespace="QuickFlow.UI.ListForm" TagPrefix="QFL" %>
<%@ Register Src="DataEdit.ascx" TagName="DataEdit" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="form.css" rel="stylesheet" type="text/css" />
    <SharePoint:ScriptLink ID="ScriptLink1" Language="javascript" Name="core.js" Defer="true"
        runat="server" />
    <SharePoint:CustomJSUrl ID="CustomJSUrl1" runat="server" />
    <SharePoint:CssLink ID="CssLink1" runat="server" />
    <SharePoint:Theme ID="theme1" runat="server" />
</head>
<body>
    <form id="form1" runat="server">
    <QFL:ListFormControl ID="ListFormControl1" runat="server">
        <uc1:DataEdit ID="DataEdit1" runat="server" />
         <table width="735" border="0" align="center" cellpadding="0" cellspacing="0" class="table_stroke">
            <tr>
                <td align="right">
                    <QFC:StartWorkflowButton Text="提交"
                     WorkflowName="信息资源申请流程" ID="StartWorkflowButton1" runat="server" />
                      <input type=button onclick="history.back()" value="返回" />
                </td>
            </tr>
        </table>
    </QFL:ListFormControl>
    <SharePoint:FormDigest ID="FormDigest1" runat="server">
    </SharePoint:FormDigest>
    </form>
</body>
</html>
 

NewForm.aspx采用ListFormControl 作为容器控件容纳所有的FormField,并且添加了StartWorkflow按钮来启动工作流,StartWorkflow的WorkflowName来制定关联的流程名称。

Step3)创建审批页面-ApproveForm.aspx,先看代码:

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Register Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
    Namespace="Microsoft.SharePoint.WebControls" TagPrefix="SharePoint" %>
<%@ Register Assembly="QuickFlow.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628"
    Namespace="QuickFlow.UI.ListForm" TagPrefix="QFL" %>
<%@ Register Assembly="QuickFlow.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628"
    Namespace="QuickFlow.UI.Controls" TagPrefix="QFC" %>
<%@ Assembly Name="QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628" %>
<%@ Register Src="DataView.ascx" TagName="DataView" TagPrefix="uc1" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <link href="form.css" rel="stylesheet" type="text/css" />
    <SharePoint:ScriptLink ID="ScriptLink1" Language="javascript" Name="core.js" Defer="true"
        runat="server" />
    <SharePoint:CustomJSUrl ID="CustomJSUrl1" runat="server" />
    <SharePoint:CssLink ID="CssLink1" runat="server" />
    <SharePoint:Theme ID="theme1" runat="server" />
</head>
<body>
    <form id="form1" runat="server">
    <QFL:ListFormControl ID="ListFormControl2" runat="server">
        <uc1:DataView ID="DataView1" runat="server" />
        <br/>
        <table width="735" border="0" align="center" cellpadding="0" cellspacing="0" class="table_stroke">
            <tr>
            <td class="form-label" width="200px">
            审批意见
            </td>
                <td>
                    <QFL:TaskPanel runat="server" ID="task1">
                        <QFL:CommentTaskField runat="server" ID="body" />
                    </QFL:TaskPanel>
                </td>
            </tr>
            <tr>
                <td align="right" colspan="2" class="form-label">
                    <QFC:ActionsButton ID="ActionsButton1" runat="server"></QFC:ActionsButton>
                    <input type="button" onclick="history.back()" value="返回" />
                </td>
            </tr>
        </table>
    </QFL:ListFormControl>
    <SharePoint:FormDigest ID="FormDigest1" runat="server">
    </SharePoint:FormDigest>
    </form>
</body>
</html>
ApproveForm.aspx跟NewForm.aspx很类似,为了实现多次循环审批时保留审批意见,QuickFlow默认的审批意见是保存
在任务列表项中,需要用另外一个容器控件TaskPanel来控制任务列表项字段。
TaskPanel内部可以放置TaskField控件,用TaskField可以直接修改当前任务的字段,CommentTaskField是一个标准的TaskField,跟任务的Body字段对应。
如果想要控制任务的其他字段,可以直接利用TaskField:
 <QFL:TaskPanelrunat="server"ID="task1">
<QFL:TaskFieldrunat="server"ID="taskF2" TaskFieldName="SomeFieldName"/></QFL:TaskPanel>
在循环审批的场景下,TaskField特别有用:采用TaskField,任务数据(如审批意见)是分散存储在各自的任务中的,不会出现下一及审批人
覆盖上一级审批数据的情况。
Step4)创建打回时修改的页面-RejectedForm.aspx
RejectedForm.aspx跟以上两个页面类似,只不过为了编辑内容,采用了DataEdit控件,并采用CommitTaskButton按钮控件来提交任务:
<QFL:ListFormControl ID="ListFormControl2" runat="server">
        <uc1:DataView ID="DataEdit1" runat="server" />
        <table width="735" border="0" align="center" cellpadding="0" cellspacing="0" class="table_stroke">
            <tr>
            <td class="form-label" width="200px">
            审批意见
            </td>
                <td>                   
                    <QFL:TaskTraceList ID="TaskTraceList1" runat="server">
                    </QFL:TaskTraceList>                   
                </td>
            </tr>
            <tr>
                <td align="right" colspan="2" class="form-label">
                    <QFC:CommitTaskButton ID="CommitTaskButton1" runat="server" Text="提交" />
                    <input type="button" onclick="history.back()" value="返回" />
                </td>
            </tr>
        </table>
    </QFL:ListFormControl>
 
Step5)页面开发完了,我们来将他们跟SharePoint关联起来。
首先,将所有页面部署到Layouts目录,本文的示例项目代码中有个DeployLayouts.cmd批处理文件,这个文件将所有页面部署到
Layouts/QuickFlowExample_DesignerAndCustomFor目录。
用QuickFlowDesigner打开上一节我们设计的流程,修改个节点的TaskFormURL属性,指定为相应的页面,如下图:
image 
image 
审批页面的关联采用QuickFlowDesigner即可,那么提交页面呢?
为了方便用户操作,我们希望用户点击新建按钮就可以直接跳到提交页面。
image
有两种方式可以实现这一点:
1)自定一个内容类型,在内容类型中指定新建和编辑,查看页面。
2)采用SPCamlEditor直接诶修改默认内容类型的页面路径。
用SPCamlEditor打开站点,定位到“信息资源申请”列表的默认内容类型,单击右键属性菜单,
修改NewFormUrl属性为:/_layouts/QuickFlowExample_DesignerAndCustomForm/NewForm.aspx
修改EditFormUrl和DispFormUrl属性为:/_layouts/QuickFlowExample_DesignerAndCustomForm/DispForm.aspx
如下图:
image
SPCamlEditor1.2具有这个功能,请到以下地址下载:http://spcamleditor.codeplex.com/
后记:url路径最好不要加 "/", 否则,根站没问题,但是子站会出现找不到页面或其他错误。
下面,就可以来测试这个流程了:
提交:
image
审批:
image
重新提交:
image
 
示例代码下载:
http://quickflow.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=34627#DownloadId=92600
or: http://cid-7f5a25cdf47d03e6.office.live.com/self.aspx/QuickFlow/Examples/QuickFlowExample%5E_DesignerAndCustomForm.zip
 注:对VS2008+QuickFlow开发的流程,本文讲解的自定义表单方法也是适用的。
      TaskFormUrl属性说明:
      任务活动的TaskFormUrl属性支持 http://    _layouts/    ~site  ~sitecolection, 文件名五种形式
	1)http://xxx.aspx指定绝对路径
	2)_layouts/folder/xxx.aspx指定layouts目录下路径
	3)~site/xxx.apx 指定相对当前站点的路径
	4)~sitecollection指定相对跟站点的路径
        5)如果指定了列表内容类型的NewFormUrl,且TaskForm跟NewForm在一个文件夹内,可以只指定文件名。
 令:
ListForm支持的控件列表如下: (切换到aspx编辑状态,把QuickFlow.UI.dll加到工具箱,可以看到所有控件,直接拖入aspx中即可使用)

控件

功能

ListFormControl

容器控件,所有控件必须在ListFormControl之内

FormField

数据字段,所有的DataField字段都是列表的字段,必须先在列表上创建好,可以通过列表的字段管理控制字段的类型(<lf:FormField ID="FormField1" runat="server" FieldName="Title“/>)

TaskPanel

TaskField容器控件,所有的taskField必须在TaskPanel内

CommentTaskField

审批任务TaskField

OutcomeTaskField

审批结果TaskField,单选框

StartWorkflowButton

启动工作流按钮

CommitTaskButton

提交任务按钮

ActionsButton

审批动作按钮,如:同意,拒绝。按照流程图自动生成

WorkflowHistory

任务跟踪控件,显示当前流程所有已完成的任务

 ReassignTaskButton  重新分配任务按钮
 
posted on 2009-11-12 22:08  jianyi  阅读(6629)  评论(86编辑  收藏  举报