Рассмотрим проблему на примере приложения «Личный кабинет». В разделе «Новости» существует форма со списком задач (Рис.1). Каждый элемент списка содержит кнопки «Выполнить» и «Завершить». Кнопка «Выполнить» открывает всплывающее окно, форма содержимого которого зависит от типа задачи, кнопка «Завершить» - завершает задачу. Обработка нажатия этих кнопок реализована в контроллере PerformCompleteWorkController (обработчики PerformWork_Execute и CompleteWork_Execute).

На каждой всплывающей форме есть две или более кнопок, названия которых зависят от типа задачи. Одна из этих кнопок так же завершает задачу. Рассмотрим форму оформления заявки на командировку сотрудником (Рис 2). Кнопка «Сохранить» сохраняет сделанные пользователем изменения и закрывает окно (это стандартная кнопка «Ок» (AcceptAction) диалогового окна). Кнопка «Отправить на утверждение» должна делать то же самое и кроме того завершать текущую задачу, таким образом переводя бизнес-процесс по командировкам на следующий этап.

Кнопка описана в контроллере RejectRequestController:

[code]
public partial class RejectRequestController : DialogController
{
private SimpleAction reject;

//private IContainer components;

public RejectRequestController()
{
InitializeComponent();
RegisterActions(components);
}

protected override void OnActivated()
{
base.OnActivated();
this.CancelAction.Active["StandardCancelActionVisible"] = false;

}

private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.reject = new DevExpress.ExpressApp.Actions.SimpleAction(this.components);
//
// reject
//
this.reject.Caption = "Отклонить";
this.reject.Category = "PopupActions";
this.reject.ConfirmationMessage = null;
this.reject.Id = "RejectRequest";
this.reject.ImageName = null;
this.reject.Shortcut = null;
this.reject.Tag = null;
this.reject.TargetObjectsCriteria = null;
this.reject.TargetObjectType = null;
this.reject.TargetViewId = null;
this.reject.ToolTip = null;
this.reject.TypeOfView = null;

}

public SimpleAction RejectRequest
{
get
{
return this.reject;
}
}

}
[/code]

Приведенный контроллер добавляет на форму кнопки при создании окна следующим образом:

[code]
private void PerformWork_Execute(object sender, SimpleActionExecuteEventArgs e)
{
ToDoItem work = (ToDoItem)e.CurrentObject;
IObjectSpace objectSpace = Application.CreateObjectSpace();
. . . . .
// определение Id необходимого для открытия View
. . . . .
if (viewId != string.Empty)
{
// Создание всплывающего окна
e.ShowViewParameters.CreatedView = Application.CreateDetailView(objectSpace, viewId, true, objectSpace.GetObject(work.ProcessInstance.BaseRequest));
e.ShowViewParameters.TargetWindow = TargetWindow.NewModalWindow;
e.ShowViewParameters.Context = TemplateContext.PopupWindow;
e.ShowViewParameters.CreateAllControllers = true;
if (viewId == "BusinessTripRequest_Карточка_User")
{
var dc = Application.CreateController<RejectRequestController>();
dc.AcceptRequest.Caption = "Отправить на утверждение";
dc.AcceptRequest.ConfirmationMessage = null;
dc.AcceptRequest.Execute += new SimpleActionExecuteEventHandler(CompleteWork_Execute);
e.ShowViewParameters.Controllers.Add(dc);
}
. . . . .
}
. . . . .
}
[/code]

После нажатия «Отправить на утверждение» список задач на заднем плане должен обновиться: поле «Состояние» должно принять значение «Завершена». Задача должна исчезнуть из списка задач, так как установлен фильтр «Актуальные», который позволяет отражаться только задачам со статусом «Не начата» и «В процессе». Но данные на форме не обновляются. Обновление (перерисовка) происходит только после нажатия стандартной кнопки «Обновить».

Решение проблемы:

Поскольку обновление будет срабатывать только после нажатия стандартной кнопки "Ок", обходным решением проблемы будет использование "2-х кнопок «Ок»". Для этого при создании окна в коллекцию e.ShowViewParameters.Controllers будем добавлять не только наш RejectRequestController но и стандартный DialogController. В качестве кнопки «Сохранить» будем использовать AcceptAction класса DialogController. В качестве кнопки «Отправить на утверждение» используем AcceptAction класса RejectRequestController. Таким образом, обновление родительского View (списка задач) будет осуществляться после нажатию любой из этих кнопок. Соответственно изменим код функции PerformWork_Execute следующим образом:

[code]
private void PerformWork_Execute(object sender, SimpleActionExecuteEventArgs e)
{

//WebWindow.CurrentRequestWindow.RegisterClientScript("Комментарий", "confirm('Желательно прокомментировать отказ !!!')"); //if(confirm('Are you sure to save? The rule is broken.')) { alert('Confirmed! Want to invoke ObjectSpace.CommitChanges.'); } else { alert('Cancelled! No save...'); }
ToDoItem work = (ToDoItem)e.CurrentObject;
if (work.ProcessInstance != null && work.ProcessInstance.ProcessDescription != null && work.StatusWork != StatusWork.Complete)
{
IObjectSpace objectSpace = Application.CreateObjectSpace();
string viewId = string.Empty;
switch (work.ProcessInstance.ProcessStage.QueueNumber)
{
// Первая стадия бизнес-процесса
case 1:
switch (work.ProcessInstance.ProcessDescription.Name)
{
case "Командировки":
viewId = "BusinessTripRequest_Карточка_User";
if (work.ProcessInstance.BaseRequest == null) work.ProcessInstance.BaseRequest = View.ObjectSpace.CreateObject<BusinessTripRequest>();
break;
// ...
}
break;
// ...
default:
break;
}//switch(QueueNumber)

work.StatusWork = StatusWork.InProcess;
if (viewId != string.Empty)
{
e.ShowViewParameters.CreatedView = Application.CreateDetailView(objectSpace, viewId, true, objectSpace.GetObject(work.ProcessInstance.BaseRequest));
e.ShowViewParameters.TargetWindow = TargetWindow.NewModalWindow;
e.ShowViewParameters.Context = TemplateContext.PopupWindow;
e.ShowViewParameters.CreateAllControllers = true;

if (e.ShowViewParameters.CreatedView.ObjectTypeInfo.Type == typeof(BusinessTripRequest))
{
var standardController = Application.CreateController<DialogController>();
standardController.AcceptAction.Caption = "Сохранить";
standardController.AcceptAction.ToolTip = "Сохранить изменения и закрыть окно";
standardController.CancelAction.Active["StandardCancelActionVisible"] = false;
e.ShowViewParameters.Controllers.Add(standardController);
}

(e.ShowViewParameters.CreatedView as DetailView).ViewEditMode = DevExpress.ExpressApp.Editors.ViewEditMode.Edit;
}
}
View.ObjectSpace.CommitChanges();
}
[/code]