Task 1: Define the Workflow Parameters

A workflow and a host application can pass data between them by using parameters. On the workflow side, a parameter is a property that is defined in your workflow class. If a set method is defined for the property, the host application can set that property before the workflow executes by passing in a Parameters collection during the CreateWorkflow method call. To return parameters back to the host application after it finishes running, you can define a get method for the property. The host application can then access the WorkflowCompletedEventArgs object that is passed to the WorkflowCompleted event. The WorkflowCompletedEventArgs object contains all the properties defined in the workflow that contain get methods.

In this task, you create an integer property named Amount. This property is passed to the workflow when the expense report is submitted. The workflow processes the amount and communicates back to the workflow for approval or rejection. Then it sets its Result string property, which the host application can access when the workflow finishes running.

Note

Although you are encouraged to follow the exercises in a linear manner, it is not required. You can start this exercise by opening the sample project, and then proceeding to the steps in the following section.

Defining the Workflow Properties

Follow these steps to define an integer property for the amount and a string property for the result.

To define the Amount and Result workflow properties

  1. Open the ExpenseReportWorkflow project.

  2. Open Workflow1.cs and in the ExpenseReportWorkflow class, declare a private Int32 field named reportAmount and a private String field named reportResult.

    private int reportAmount = 0;
    
    private string reportResult = "";
    
  3. Create a public Int32 property that which sets the reportAmount field that you created in the previous step.

    public int Amount
    {
        set
        {
            this.reportAmount = value;
        }
    }
    
  4. Create a public String property that returns the value of the reportResult field that you created in step two.

    public string Result
    {
        get
        {
            return this.reportResult;
        }
    }
    

Modifying the Windows Form Application

Next, you modify the Windows Form application to set the Amount property of the ExpenseReportWorkflow and to retrieve the Result property when the workflow has finished running. You set the Amount property when you create the workflow, and you retrieve the Result property when the WorkflowCompleted event is raised.

To set the Amount workflow property

  1. Open Form1.cs.

  2. In the submitButton_Click method in the MainForm class, create a generic Dictionary collection of the Object type named properties that uses a String for the key.

    Note

    You must add this code before you call the CreateWorkflow method.

    // Construct workflow parameters
    Dictionary<string, object> properties = new Dictionary<string, object>();
    
  3. Call the Add method defined on the properties collection that you just created, passing in the string "Amount" as the first parameter and the Text property of the amount TextBox control converted to an Int32 value.

    When the workflow starts, the WorkflowRuntime uses this information to set the workflow's Amount property.

    properties.Add("Amount", Int32.Parse(this.amount.Text));
    
  4. Modify the CreateWorkflow method call on the next line by passing the properties collection as the second parameter.

    workflowInstance = workflowRuntime.CreateWorkflow(type, properties);
    

    The revised submitButton_Click method now looks like the following:

    private void submitButton_Click(object sender, EventArgs e)
    {
        Type type = typeof(ExpenseReportWorkflow.ExpenseReportWorkflow);
    
        // Construct workflow parameters
        Dictionary<string, object> properties = new Dictionary<string, object>();
        properties.Add("Amount", Int32.Parse(this.amount.Text));
    
        // Start the workflow.
        workflowInstance = workflowRuntime.CreateWorkflow(type, properties);
        this.workflowInstance.Start();
    }
    

To retrieve the Result workflow property

  1. In the workflowRuntime_WorkflowCompleted method in the MainForm class, add an If statement to verify InvokeRequired is true for the result TextBox control.

    You must perform this action because the workflow instance runs on a separate thread, and updating the UI requires you to invoke operations from the UI thread.

  2. In the true branch of the If statement, call the Invoke method from the result TextBox control, passing a new generic EventHandler of the WorkflowCompletedEventArgs type named workflowRuntime_WorkflowCompleted.

    Pass the sender and e local variable as parameters to the event handler.

        if (this.result.InvokeRequired)
        {
            this.result.Invoke(new EventHandler<WorkflowCompletedEventArgs>
    (this.workflowRuntime_WorkflowCompleted), sender, e);
        }
    
  3. In the else branch of the If statement, set the Text property of the result TextBox control equal to the "Result" key of the OutputParameters collection defined in the e parameter.

    Make sure that you call the ToString method to convert the value to a string.

  4. Clear the amount TextBox control by setting its Text property to String.Empty.

  5. Disable the approveButton and rejectButton Button controls by setting their Enabled properties to false.

    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;
    
    }
    

    The final workflowRuntime_WorkflowCompleted method implementation looks like the following:

    void workflowRuntime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
    {
    
        if (this.result.InvokeRequired)
        {
            this.result.Invoke(new EventHandler<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;
        }
    }
    

In Task 2: Define the IExpenseReportService Interface, you create the interface that enables the workflow and host application to communicate.

See Also

Reference

CreateWorkflow
WorkflowCompleted
WorkflowCompletedEventArgs
OutputParameters

Other Resources

Task 2: Define the IExpenseReportService Interface

Copyright © 2007 by Microsoft Corporation. All rights reserved.
Last Published: 2010-03-04