При разработке собственных рабочих процессов, вам придётся самим программно создавать задания. При использовании Activity CreateTaskWithContentType, указывая тип контента, можно использовать свои формы инициации, ассоциации и редактирования для задания. В данной статье решил показать как создать форму для редактирования задания.
Создание формы
Открываем Visual Studio (я использую Visual Studio 2010) — Открываем “File Menu” — Выбираем “New” — Выбираем “Web Site” — Выбираем “ASP.NET Web Site” — Меняем тип на HTTP (это очень важно) — Выбираем местоположение: http://localhost/_layouts/AgreementTaskEditForm. IIS скопирует ваши файлы в директорию C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS

— Жмём “OK”, для создания. — Удаляем файлы About.aspx, Default.aspx и SiteMaster
— Создаём папку TaskEditForm. — Жмём на неё правой кнопкой и выбираем “Add New Item” — Выбираем “Web Form” — Называем форму “TaskEditForm.aspx” — Выбираем “Place code in separate file” — Жмём “Add”

После манипуляций проект выглядит как-то так:

Добавляем вверху aspx файла:
1.
<%@ Register TagPrefix=
"SharePoint"
2.
Namespace=
"Microsoft.SharePoint.WebControls"
3.
Assembly=
"Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
%>
4.
5.
<%@ Register TagPrefix=
"Utilities"
6.
Namespace=
"Microsoft.SharePoint.Utilities"
7.
Assembly=
"Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
%>
Всё остальное удаляем. Добавляем:
1.
<asp:Content ContentPlaceHolderID=
"PlaceHolderMain"
runat=
"server"
>
2.
<%-- Начало кода контрола --%>
3.
<%-- Конец кода контрола --%>
4.
<%-- Тэг, который указывает SharePoint, что мы будем постить данные в форму--%>
5.
<SharePoint:FormDigest ID=
"FormDigest1"
runat=
"server"
/>
6.
</asp:Content>
Теперь внутрь управляющего коннтрола добавляем элементы управления, которые нам нужны. Более-менее в приличный вид для отображения приведём. В итоге файл выглядит примерно так:
01.
<%@ Register TagPrefix="SharePoint"
02.
Namespace="Microsoft.SharePoint.WebControls"
03.
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
04.
05.
<%@ Register TagPrefix="Utilities"
06.
Namespace="Microsoft.SharePoint.Utilities"
07.
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
08.
09.
<%@ Register TagPrefix="spuc" Namespace="Microsoft.SharePoint.WebControls"
10.
Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
11.
12.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TaskEditForm.aspx.cs" Inherits="TaskEditForm_TaskEditForm" %>
13.
14.
<
asp:Content
ContentPlaceHolderID
=
"PlaceHolderMain"
runat
=
"server"
>
15.
<
div
id
=
"ApproveForm"
style
=
"margin-left: auto; margin-top:50px; margin-right: auto; width:800px; "
>
16.
17.
<
div
id
=
"DataField"
style
=
" -moz-box-sizing: border-box;"
>
18.
<
table
id
=
"DataT"
>
19.
<
tr
>
20.
<
td
style
=
"width:200px;"
class
=
"DataTtd DataTLabelTd"
>
21.
<
p
style
=
"margin-right:20px; margin-left:20px;"
>Состояние:</
p
>
22.
23.
</
td
>
24.
<
td
class
=
"DataTDataTd DataTtd"
>
25.
<
asp:TextBox
CssClass
=
"tbx"
26.
ID
=
"TaskStatus"
Width
=
"500"
runat
=
"server"
Text
=
""
Enabled
=
"false"
>
27.
</
asp:TextBox
>
28.
29.
</
td
>
30.
</
tr
>
31.
32.
<
tr
>
33.
<
td
style
=
"width:200px;"
class
=
"DataTtd DataTLabelTd"
>
34.
<
p
style
=
"margin-right:20px; margin-left:20px;"
>Срок выполнения:</
p
>
35.
</
td
>
36.
<
td
class
=
"DataTDataTd DataTtd "
>
37.
<
spuc:DateTimeControl
Enabled
=
"false"
runat
=
"server"
ID
=
"DueDate"
CssClassTextBox
=
"DataTimePicerCSS"
DateOnly
=
"true"
/>
38.
</
td
>
39.
</
tr
>
40.
<
tr
>
41.
42.
<
td
style
=
"width:200px;"
class
=
"DataTtd DataTLabelTd"
>
43.
<
p
style
=
"margin-right:20px; margin-left:20px;"
>Примечание:</
p
>
44.
</
td
>
45.
<
td
class
=
"DataTDataTd DataTtd "
>
46.
<
asp:TextBox
CssClass
=
"tbx"
ID
=
"Note"
47.
runat
=
"server"
rows
=
"5"
TextMode
=
"multiline"
Text
=
""
></
asp:TextBox
>
48.
</
td
>
49.
</
tr
>
50.
51.
</
table
>
52.
53.
</
div
>
54.
55.
<
div
id
=
"BtnsField"
>
56.
<
asp:Panel
ID
=
"Btns_Panel"
runat
=
"server"
>
57.
<
asp:Button
ID
=
"btnApprove"
onclick
=
"btnApprove_Click"
runat
=
"server"
Text
=
"Утвердить"
/>
58.
59.
<
asp:Button
ID
=
"btnCancel"
onclick
=
"btnCancel_Click"
runat
=
"server"
Text
=
"Отмена"
/>
60.
61.
</
asp:Panel
>
62.
</
div
>
63.
64.
</
div
>
65.
<
SharePoint:FormDigest
ID
=
"FormDigest1"
runat
=
"server"
/>
66.
</
asp:Content
>
Где-то сверху css-стили добавим:
01.
<style type=
"text/css"
>
02.
03.
#DataT tr, #DataT, #DataTReAssigned, #DataTReAssigned tr
04.
{
05.
padding
:
0px
;
06.
border-collapse
:
collapse
;
07.
}
08.
#DataT
09.
10.
.DataTtd
11.
{
12.
padding-bottom
:
10px
;
13.
padding-left
:
0px
;
14.
padding-right
:
0px
;
15.
border-bottom
:
1pt
solid
#D8D8D8
;
16.
border-top
:
1pt
solid
#D8D8D8
;
17.
18.
}
19.
.DataTDataTd
20.
{
21.
background-color
:
#F5F6F7
;
22.
width
:
600px
;
23.
}
24.
25.
.DataTLabelTd
26.
{
27.
width
:
200px
;
28.
}
29.
30.
.tbx, .DataTimePicerCSS
31.
{
32.
-moz-box-sizing: border-box;
33.
font-family
: Times New Roman;
34.
font-size
:
12pt
;
35.
font-style
:
normal
;
36.
font-weight
:
normal
;
37.
text-align
:
left
;
38.
white-space
:
normal
;
39.
width
:
500px
;
40.
margin-left
:
20px
;
41.
}
42.
#ctl
00
_PlaceHolderMain_Author_upLevelDiv, #ctl
00
_PlaceHolderMain_AssignedToPE_upLevelDiv
43.
{
44.
height
:
20px
!important
;
45.
width
:
500px
;
46.
border
:
1px
solid
#828790
;
47.
padding-top
:
5px
;
48.
margin-left
:
20px
;
49.
}
50.
#ctl
00
_PlaceHolderMain_FileUpload
1
51.
{
52.
margin-left
:
20px
;
53.
}
54.
#BtnsField, #BtnsFieldReAssigned
55.
{
56.
border-left
:
1pt
solid
#D8D8D8
;
57.
border-right
:
1pt
solid
#D8D8D8
;
58.
border-bottom
:
1pt
solid
#D8D8D8
;
59.
padding-top
:
15px
;
60.
text-align
:
center
;
61.
padding-bottom
:
20px
;
62.
}
63.
64.
65.
</style>
Написание кода для формы
Форма редактирования вне проекта рабочего процесса. Поэтому необходимо использовать внешние методы для работы со списками и заданиями. Для начала подключаем соответствующие библиотеки:
1.
using
System.Web.UI.WebControls;
2.
using
Microsoft.SharePoint;
3.
using
Microsoft.SharePoint.Workflow;
4.
using
Microsoft.SharePoint.Utilities;
Вы увидите так же методы для обработки действий кнопок и метод, вызывающийся при загрузке страницы:
01.
protected
void
Page_Load(
object
sender, EventArgs e)
02.
{
03.
04.
}
05.
protected
void
btnCancel_Click(
object
sender, EventArgs e)
06.
{
07.
08.
}
09.
protected
void
btnApprove_Click(
object
sender, EventArgs e)
10.
{
11.
}
Они то и реализуют всю магию. Но для начала необходимо переменные для работы определить.
01.
#region переменные задания
02.
03.
protected
SPList _TaskListAttachedTo;
// список задания рабочего процесса
04.
protected
SPListItem _TaskListItem;
// список в задании
05.
protected
string
_myTaskData;
// данные от юзера, которые посланы в р.б.
06.
string
_paramTaskListItemID;
// ID Task List Item
07.
08.
#endregion
09.
10.
#region параметры рабочего процесса
11.
12.
string
_paramSPListGuid =
string
.Empty;
// GUID списка, с которым заатачились
13.
SPWorkflow _activeWorkflow;
// Текущий р.б.
14.
Guid _workflowInstanceGuid;
// Айдишник р.б.
15.
public
Microsoft.SharePoint.Workflow. SPWorkflowActivationProperties workflowProperties =
16.
new
Microsoft.SharePoint.Workflow. SPWorkflowActivationProperties();
17.
#endregion
Получение параметров рабочего процесса
Для начала нам необходимо параметры получить.
1.
private
void
getWorkflowParameters()
2.
{
3.
this
._paramSPListGuid = Request.Params[
"List"
];
// The SharePoint Document Libary ID
4.
this
._paramTaskListItemID = Request.Params[
"ID"
];
// The associated Task Lists ID
5.
}
Загрузка MasterPage
01.
// Переопределение метода. Запускатеся при иницилазации.
02.
// ммм...здесь программно можно задать, какой мастер юзать
03.
protected
override
void
OnPreInit(EventArgs e)
04.
{
05.
base
.OnPreInit(e);
06.
07.
// Текущая страница
08.
string
pageName = Page.AppRelativeVirtualPath.Substring(
09.
Page.AppRelativeVirtualPath.LastIndexOf(
'/'
) + 1);
10.
11.
// Если в десижнере
12.
if
(pageName.Substring(0, 6).ToUpper() ==
"Design"
.ToUpper())
13.
{
14.
15.
this
._myPoratlSite =
new
SPSite(
"http://localhost/"
);
16.
SPControl.SetContextSite(Context,
this
._myPoratlSite);
17.
18.
this
._myTeamSite = SPControl.GetContextWeb(Context).Webs[
"Site1"
];
19.
}
20.
else
21.
{
22.
this
._myTeamSite = SPControl.GetContextWeb(Context);
23.
this
.MasterPageFile = _myTeamSite.MasterUrl;
24.
}
25.
26.
}
Получение информации о списке и рабочем процессе
Теперь необходимо получить параметры рабочего процесса и задания.
01.
private
void
getTaskListInformation()
02.
{
03.
// Получаем Task List that, к которму приатачены
04.
this
._TaskListAttachedTo =
this
._myTeamSite.Lists[
new
Guid(
this
._paramSPListGuid)];
05.
06.
// Получаем Task Item Object, который WF создал
07.
this
._TaskListItem =
this
._TaskListAttachedTo.GetItemById( System.Convert.ToInt16(
this
._paramTaskListItemID));
08.
09.
// Получаем ID Workflow Instance
10.
this
._workflowInstanceGuid =
new
Guid(Convert.ToString(
this
._TaskListItem[
"WorkflowInstanceID"
]));
11.
12.
this
._activeWorkflow =
new
SPWorkflow(
this
._TaskListItem,
this
._workflowInstanceGuid);
13.
14.
}
Получение информации из списка
Теперь, когда нам известна общая информация о списке и рабочем процессе, можно получить информацию о нашем конкретном задании.
01.
private
void
getTaskInformation()
02.
{
03.
// Получаем статус
04.
if
(
this
._TaskListItem[
"ows_Status"
] !=
null
)
05.
{
06.
TaskStatus.Text =
this
._TaskListItem[
"ows_Status"
].ToString();
07.
}
08.
// Получаем информацию о сроках
09.
if
(
this
._TaskListItem[
"ows_DueDate"
] !=
null
)
10.
DueDate.SelectedDate = Convert.ToDateTime(
this
._TaskListItem[
"ows_DueDate"
]);
11.
12.
13.
// Получаем комментарий
14.
string
sNote = GetParam(
"ows_Note"
);
15.
if
(sNote !=
string
.Empty)
16.
Note.Text = sNote;
17.
}
Добавляем в Page_load метод
1.
protected
void
Page_Load(
object
sender, EventArgs e)
2.
{
3.
if
(!IsPostBack)
4.
RBList.SelectedIndex = 0;
5.
getWorkflowParameters();
6.
getTaskListInformation();
7.
getTaskInformation();
8.
}
Методы для обработки действий кнопок
Осталось лишь написать методы, которые будут обрабатывать действия кнопок.
01.
// Отмена
02.
protected
void
btnCancel_Click(
object
sender, EventArgs e)
03.
{
04.
// просто делаем редирет в библиотеку
05.
SPUtility.Redirect(
this
._TaskListAttachedTo.DefaultViewUrl,
06.
SPRedirectFlags.UseSource,
07.
HttpContext.Current);
08.
}
09.
10.
// При утверждении
11.
protected
void
btnApprove_Click(
object
sender, EventArgs e)
12.
{
13.
14.
Hashtable taskHash =
new
Hashtable();
15.
taskHash[
"Result"
] =
"Утвёрждён"
;
// кастомное поле "Результат"
16.
taskHash[
"PercentComplete"
] =
"1"
;
// 1 = 100%. .9 = 90%
17.
taskHash[
"Note"
] = Note.Text;
// кастомное поле "Примечание"
18.
// обновляем информации о задании
19.
SPWorkflowTask.AlterTask(
this
._TaskListItem, taskHash,
true
);
20.
21.
22.
SPUtility.Redirect(
this
._TaskListAttachedTo.DefaultViewUrl,
23.
SPRedirectFlags.UseSource,
24.
HttpContext.Current);
25.
26.
}
По аналогии можно новые элементы на форму добавлять. Теперь необходимо тип контента свой создать (который мы завяжем на эту форму), чтобы в рабочем процессе при создании указать наш тип контента с нашей формой редактирования.
Уведомление: Прикрепить файл в рабочем процессе в своей форме | Suvitruf's Blog
Уведомление: Создание своего типа контента для SharePoint | Suvitruf's Blog
it will be really work out with my blog. Thanks for sharing with us!
Уведомление: Получение параметров из ExtendedProperties задания на форме редактирования в рамках рабочего процесса SharePoint | Suvitruf's Blog