Problem with Tutorial - Creating a Sequential Workflow
Has anyone been able to get this Tutorial on the MSDN site to work? I am having multiple problems running this. I have posted my 2 code files below. Would appreciate if someone could compile the files and let me know what is wrong. Thanks in advance, Arshad.
1.) I get the error: Event ExpenseReportApproved on interface type "Microsoft.Samples.Workflow.Tutorials.SequentialWorkflow.IExpenseReportService" for instance id "88###" cannot be delivered.
2.) The buttons for Approve and Reject are disabled by default. I commented the responsible code as below:
void workflowRuntime_WorkflowCompleted(object sender,WorkflowCompletedEventArgs e)
{
if (this.result.InvokeRequired)
{
this.result.Invoke(newEventHandler<WorkflowCompletedEventArgs> (this.workflowRuntime_WorkflowCompleted), sender, e);
}
else
{
this.result.Text = e.OutputParameters["Result"].ToString();
// Clear fields
this.amount.Text =string.Empty;
// Disable buttons
//this.approveButton.Enabled = false;
//this.rejectButton.Enabled = false;
}
3.) There is no code for the approveEvent_Invoked event
Below is the code for my 2 files: Program.cs and SimpleExpenseReport.cs
******************************************Program.cs ***********************
using
System;using
System.ComponentModel;using
System.Drawing;using
System.Windows.Forms;using
System.Collections.Generic;using
System.Workflow.Runtime;using
System.Workflow.Runtime.Hosting;using
System.Workflow.Activities;using
System.Threading;namespace
Microsoft.Samples.Workflow.Tutorials.SequentialWorkflow{
[Serializable]
publicclassMainForm :Form,IExpenseReportService
{
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox result;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Button submitButton;
private System.Windows.Forms.Label approvalState;
private System.Windows.Forms.Button approveButton;
private System.Windows.Forms.Button rejectButton;
private System.Windows.Forms.TextBox amount;
private System.Windows.Forms.Panel panel1;
privateWorkflowRuntime workflowRuntime =null;
privateWorkflowInstance workflowInstance =null;
private System.ComponentModel.IContainer components =null;
privatedelegatevoidGetApprovalDelegate(string message);
publiceventEventHandler<ExternalDataEventArgs> ExpenseReportApproved;
publiceventEventHandler<ExternalDataEventArgs> ExpenseReportRejected;
privateExternalDataExchangeService exchangeService =null;
public MainForm()
{
InitializeComponent();
this.exchangeService =newExternalDataExchangeService();
this.workflowRuntime =newWorkflowRuntime();
workflowRuntime.AddService(exchangeService);
exchangeService.AddService(this);
workflowRuntime.StartRuntime();
workflowRuntime.WorkflowCompleted +=
newEventHandler<WorkflowCompletedEventArgs>
(workflowRuntime_WorkflowCompleted);
// Collapse approve/reject panel
this.Height -=this.panel1.Height;
}
protectedoverridevoid Dispose(bool disposing)
{
if (disposing && (components !=null))
{
components.Dispose();
}
base.Dispose(disposing);
}
privatevoid InitializeComponent()
{
this.label1 =new System.Windows.Forms.Label();
this.result =new System.Windows.Forms.TextBox();
this.label2 =new System.Windows.Forms.Label();
this.submitButton =new System.Windows.Forms.Button();
this.approvalState =new System.Windows.Forms.Label();
this.approveButton =new System.Windows.Forms.Button();
this.rejectButton =new System.Windows.Forms.Button();
this.amount =new System.Windows.Forms.TextBox();
this.panel1 =new System.Windows.Forms.Panel();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// label1
//
this.label1.AutoSize =true;
this.label1.Location =new System.Drawing.Point(10, 13);
this.label1.Name ="label1";
this.label1.Size =new System.Drawing.Size(43, 13);
this.label1.TabIndex = 1;
this.label1.Text ="Amount";
//
// result
//
this.result.Location =new System.Drawing.Point(13, 70);
this.result.Name ="result";
this.result.ReadOnly =true;
this.result.Size =new System.Drawing.Size(162, 20);
this.result.TabIndex = 1;
this.result.TabStop =false;
//
// label2
//
this.label2.AutoSize =true;
this.label2.Location =new System.Drawing.Point(10, 54);
this.label2.Name ="label2";
this.label2.Size =new System.Drawing.Size(37, 13);
this.label2.TabIndex = 3;
this.label2.Text ="Result";
//
// submitButton
//
this.submitButton.Enabled =false;
this.submitButton.Location =new System.Drawing.Point(56, 95);
this.submitButton.Name ="submitButton";
this.submitButton.Size =new System.Drawing.Size(75, 23);
this.submitButton.TabIndex = 2;
this.submitButton.Text ="Submit";
this.submitButton.Click +=new
System.EventHandler(this.submitButton_Click);
//
// approvalState
//
this.approvalState.AutoSize =true;
this.approvalState.Location =new System.Drawing.Point(10, 9);
this.approvalState.Name ="approvalState";
this.approvalState.Size =new System.Drawing.Size(49, 13);
this.approvalState.TabIndex = 4;
this.approvalState.Text ="Approval";
//
// approveButton
//
this.approveButton.Enabled =false;
this.approveButton.Location =new System.Drawing.Point(11, 25);
this.approveButton.Name ="approveButton";
this.approveButton.Size =new System.Drawing.Size(75, 23);
this.approveButton.TabIndex = 0;
this.approveButton.Text ="Approve";
this.approveButton.Click +=new
System.EventHandler(this.approveButton_Click);
//
// rejectButton
//
this.rejectButton.Enabled =false;
this.rejectButton.Location =new System.Drawing.Point(86, 25);
this.rejectButton.Name ="rejectButton";
this.rejectButton.Size =new System.Drawing.Size(75, 23);
this.rejectButton.TabIndex = 1;
this.rejectButton.Text ="Reject";
this.rejectButton.Click +=new
System.EventHandler(this.rejectButton_Click);
//
// amount
//
this.amount.Location =new System.Drawing.Point(13, 29);
this.amount.MaxLength = 9;
this.amount.Name ="amount";
this.amount.Size =new System.Drawing.Size(162, 20);
this.amount.TabIndex = 0;
this.amount.KeyPress +=new
System.Windows.Forms.KeyPressEventHandler(this.amount_KeyPress);
this.amount.TextChanged +=new
System.EventHandler(this.amount_TextChanged);
//
// panel1
//
this.panel1.Controls.Add(this.approvalState);
this.panel1.Controls.Add(this.approveButton);
this.panel1.Controls.Add(this.rejectButton);
this.panel1.Location =new System.Drawing.Point(7, 124);
this.panel1.Name ="panel1";
this.panel1.Size =new System.Drawing.Size(172, 66);
this.panel1.TabIndex = 8;
//
// MainForm
//
this.AcceptButton =this.submitButton;
this.AutoScaleDimensions =new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize =new System.Drawing.Size(187, 201);
this.Controls.Add(this.result);
this.Controls.Add(this.label2);
this.Controls.Add(this.panel1);
this.Controls.Add(this.amount);
this.Controls.Add(this.submitButton);
this.Controls.Add(this.label1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.MaximizeBox =false;
this.MinimizeBox =false;
this.Name ="MainForm";
this.Text ="Simple Expense Report";
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
publicvoid GetLeadApproval(string message)
{
if (this.approvalState.InvokeRequired)
this.approvalState.Invoke(newGetApprovalDelegate
(this.GetLeadApproval), message);
else
{
this.approvalState.Text = message;
this.approveButton.Enabled =true;
this.rejectButton.Enabled =true;
// expand the panel
this.Height +=this.panel1.Height;
this.submitButton.Enabled =false;
}
}
publicvoid GetManagerApproval(string message)
{
if (this.approvalState.InvokeRequired)
this.approvalState.Invoke(newGetApprovalDelegate
(this.GetManagerApproval), message);
else
{
this.approvalState.Text = message;
this.approveButton.Enabled =true;
this.rejectButton.Enabled =true;
// expand the panel
this.Height +=this.panel1.Height;
this.submitButton.Enabled =false;
}
}
void workflowRuntime_WorkflowCompleted(object sender,WorkflowCompletedEventArgs e)
{
if (this.result.InvokeRequired)
{
this.result.Invoke(newEventHandler<WorkflowCompletedEventArgs>
(this.workflowRuntime_WorkflowCompleted), sender, e);
}
else
{
this.result.Text = e.OutputParameters["Result"].ToString();
// Clear fields
this.amount.Text =string.Empty;
// Disable buttons
//this.approveButton.Enabled = false;
// this.rejectButton.Enabled = false;
}
}
privatevoid submitButton_Click(object sender,EventArgs e)
{
Type type =typeof(ExpenseReportWorkflow);
// Construct workflow parameters
Dictionary<string,object> properties =newDictionary<string,object>();
properties.Add("Amount",Int32.Parse(this.amount.Text));
workflowInstance = workflowRuntime.CreateWorkflow(type, properties);
workflowInstance.Start();
}
privatevoid approveButton_Click(object sender,EventArgs e)
{
// Raise the ExpenseReportApproved event back to the workflow
ExpenseReportApproved(null,newExternalDataEventArgs
(this.workflowInstance.InstanceId));
this.Height -=this.panel1.Height;
this.submitButton.Enabled =true;
}
privatevoid rejectButton_Click(object sender,EventArgs e)
{
// Raise the ExpenseReportRejected event back to the workflow
ExpenseReportRejected(null,newExternalDataEventArgs
(this.workflowInstance.InstanceId));
this.Height -=this.panel1.Height;
this.submitButton.Enabled =true;
}
privatevoid amount_KeyPress(object sender,KeyPressEventArgs e)
{
if (!Char.IsControl(e.KeyChar) && (!Char.IsDigit(e.KeyChar)))
e.KeyChar =Char.MinValue;
}
privatevoid amount_TextChanged(object sender,EventArgs e)
{
submitButton.Enabled = amount.Text.Length > 0;
}
}
staticclassProgram
{
[STAThread]
staticvoid Main()
{
Application.EnableVisualStyles();
Application.Run(newMainForm());
}
}
}
******************************************SimpleExpenseReport.cs ***********************
using System;
using
System.Workflow.Runtime;using
System.Workflow.Activities;using
System.Workflow.Activities.Rules;using
System.Workflow.ComponentModel;namespace
Microsoft.Samples.Workflow.Tutorials.SequentialWorkflow{
publicclassExpenseReportWorkflow :SequentialWorkflowActivity
{
privateint _amount = 0;
privatestring _result ="";
privateIfElseActivity evaluateExpenseReportAmount;
privateIfElseBranchActivity ifNeedsLeadApproval;
privateIfElseBranchActivity elseNeedsManagerApproval;
privateCallExternalMethodActivity invokeGetLeadApproval;
privateCallExternalMethodActivity invokeGetManagerApproval;
privateListenActivity listenApproveReject;
privateEventDrivenActivity eventDriven1;
privateEventDrivenActivity eventDriven2;
privateHandleExternalEventActivity approveEvent;
privateHandleExternalEventActivity rejectEvent;
publicint Amount
{
set
{
this._amount =value;
}
}
publicstring Result
{
get
{
returnthis._result;
}
}
void DetermineApprovalContact(object sender,ConditionalEventArgs e)
{
if (this._amount < 1000)
{
e.Result =true;
}
else
{
e.Result =false;
}
}
public ExpenseReportWorkflow()
{
InitializeComponent();
}
privatevoid InitializeComponent()
{
this.CanModifyActivities =true;
this.eventDriven1 =newEventDrivenActivity();
this.eventDriven2 =newEventDrivenActivity();
this.listenApproveReject =newListenActivity();
this.approveEvent =newHandleExternalEventActivity();
this.rejectEvent =newHandleExternalEventActivity();
this.evaluateExpenseReportAmount =newIfElseActivity();
this.ifNeedsLeadApproval =newIfElseBranchActivity();
this.elseNeedsManagerApproval =newIfElseBranchActivity();
this.invokeGetLeadApproval =newCallExternalMethodActivity();
this.invokeGetManagerApproval =newCallExternalMethodActivity();
CodeCondition ifElseLogicStatement =newCodeCondition();
WorkflowParameterBinding workflowparameterbinding1 =
newWorkflowParameterBinding();
WorkflowParameterBinding workflowparameterbinding2 =
newWorkflowParameterBinding();
this.evaluateExpenseReportAmount.Activities.Add(this.ifNeedsLeadApproval);
this.evaluateExpenseReportAmount.Activities.Add
(this.elseNeedsManagerApproval);
this.evaluateExpenseReportAmount.Name ="evaluateExpenseReportAmount";
this.ifNeedsLeadApproval.Activities.Add(this.invokeGetLeadApproval);
ifElseLogicStatement.Condition +=new
System.EventHandler<ConditionalEventArgs>(this.DetermineApprovalContact);
this.ifNeedsLeadApproval.Condition = ifElseLogicStatement;
this.ifNeedsLeadApproval.Name ="ifNeedsLeadApproval";
this.elseNeedsManagerApproval.Activities.Add(this.invokeGetManagerApproval);
this.elseNeedsManagerApproval.Name ="elseNeedsManagerApproval";
this.invokeGetLeadApproval.InterfaceType =typeof(IExpenseReportService);
this.invokeGetLeadApproval.MethodName ="GetLeadApproval";
this.invokeGetLeadApproval.Name ="invokeGetLeadApproval";
workflowparameterbinding1.ParameterName ="message";
workflowparameterbinding1.Value ="Lead approval needed";
this.invokeGetLeadApproval.ParameterBindings.Add(workflowparameterbinding1);
this.invokeGetManagerApproval.InterfaceType =typeof(IExpenseReportService);
this.invokeGetManagerApproval.MethodName ="GetManagerApproval";
this.invokeGetManagerApproval.Name ="invokeGetManagerApproval";
workflowparameterbinding2.ParameterName ="message";
workflowparameterbinding2.Value ="Manager approval needed";
this.invokeGetManagerApproval.ParameterBindings.Add
(workflowparameterbinding2);
this.eventDriven1.Activities.Add(this.approveEvent);
this.eventDriven1.Name ="eventDriven1";
this.eventDriven2.Activities.Add(this.rejectEvent);
this.eventDriven2.Name ="eventDriven3";
this.listenApproveReject.Activities.Add(this.eventDriven1);
this.listenApproveReject.Activities.Add(this.eventDriven2);
this.listenApproveReject.Name ="listenApproveReject";
this.approveEvent.EventName ="ExpenseReportApproved";
this.approveEvent.InterfaceType =typeof(IExpenseReportService);
this.approveEvent.Name ="approveEvent";
// this.approveEvent.Invoked += new
// System.EventHandler<ExternalDataEventArgs>(this.approveEvent_Invoked);
this.rejectEvent.EventName ="ExpenseReportRejected";
this.rejectEvent.InterfaceType =typeof(IExpenseReportService);
this.rejectEvent.Name ="rejectEvent";
// this.rejectEvent.Invoked += new
// System.EventHandler<ExternalDataEventArgs>(this.rejectEvent_Invoked);
this.Activities.Add(this.evaluateExpenseReportAmount);
this.Name ="ExpenseReportWorkflow";
this.CanModifyActivities =false;
}
}
[ExternalDataExchange]
publicinterfaceIExpenseReportService
{
void GetLeadApproval(string message);
void GetManagerApproval(string message);
eventEventHandler<ExternalDataEventArgs> ExpenseReportApproved;
eventEventHandler<ExternalDataEventArgs> ExpenseReportRejected;
}
}

