Windows Workflow Foundation 3


SimpleExpenseReport


Dear all,
I tried to follow the instructions from the Windows SDK's Windows Workflow Foundation Tutorial section in order to create a sequential workflow sample. However,  I  got some trouble:
For VB version:
I got an error when try to compile code included in Exercise 3, task 1:
Error 1 :Handles clause requires a WithEvents variable defined in the containing type or one of its base types. 
The line cause error is:
Private Sub DetermineApprovalContact(ByVal sender As Object, _                  ByVal e As ConditionalEventArgs) Handles ifElseLogicStatement.Condition
I downloaded the TASK1.ZIP from the link supplied in task 2, also can't be compiled. Don't know why. So I tried the C# version.
This time, I can finish Exercise 3, task 1, but not task 2, I got the following error:
Error 1 'Microsoft.Samples.Workflow.Tutorials.SequentialWorkflow.ExpenseReportWorkflow' does not contain a definition for 'approveEvent_Invoked' 
There are 2 lines caused the error, which are:
this.approveEvent.Invoked += new                 System.EventHandler<ExternalDataEventArgs>(this.approveEvent_Invoked);
and
this.rejectEvent.Invoked += new                 System.EventHandler<ExternalDataEventArgs>(this.rejectEvent_Invoked);
Anybody know why? Or anywhere I can get a ready made version?
Thanks in advance.
Andy Ho
I was able to repro the issue with VB on the project files downloaded from the Beta 2.2 help.
 
 Andy Ho wrote:
For VB version:
I got an error when try to compile code included in Exercise 3, task 1:
Error 1 :Handles clause requires a WithEvents variable defined in the containing type or one of its base types. 
The line cause error is:
Private Sub DetermineApprovalContact(ByVal sender As Object, _                  ByVal e As ConditionalEventArgs) Handles ifElseLogicStatement.Condition
Andy,
I just compiled this sample and everything went fine. 
I did move the following code segment though to the end of the Private Sub InitializeComponet():
Me.CanModifyActivities = False
 
What build of WF are you using?
I was able to repro the issue with VB on the project files downloaded from the Beta 2.2 help.
 
 Andy Ho wrote:
For VB version:
I got an error when try to compile code included in Exercise 3, task 1:
Error 1 :Handles clause requires a WithEvents variable defined in the containing type or one of its base types. 
The line cause error is:
Private Sub DetermineApprovalContact(ByVal sender As Object, _                  ByVal e As ConditionalEventArgs) Handles ifElseLogicStatement.Condition
Tom,
Your info. really help. Thanks!
For the VB code, I can compile it now. But another runtime error occur when I approve or reject the request at the follow line:
 Me.result.Invoke(New EventHandler(Of WorkflowCompletedEventArgs) _                    (AddressOf Me.workflowRuntime_WorkflowCompleted), _                    New Object() {sender, e})
So I try the C# code, it works ok without any error, but no result display, not sure why.
Then I added a textbox and added the following line at the workflowRuntime_WorkflowCompleted section to check if the event has been fired:
this.textBox1.Text ="Completed";
The result is yes. The workflow actually completed. But no result been returned.
Any idea?
 
Andy Ho
Bill,
Can you email me a copy of your code (andyho28#hotmail.com) so that I can try on my side?
My version of WWF is 3.0.3807.7
Thanks!
Andy Ho
 
Here attached the code for your reference:
SimpleExpenseReport.vb
Imports Microsoft.VisualBasicImports SystemImports System.Workflow.RuntimeImports System.Workflow.ActivitiesImports System.Workflow.Activities.RulesImports System.Workflow.ComponentModel
Namespace Microsoft.Samples.Workflow.Tutorials.SequentialWorkflow    <ExternalDataExchange()> _    Public Interface IExpenseReportService        Sub GetLeadApproval(ByVal message As String)        Sub GetManagerApproval(ByVal message As String)        Event ExpenseReportApproved As EventHandler(Of ExternalDataEventArgs)        Event ExpenseReportRejected As EventHandler(Of ExternalDataEventArgs)    End Interface
    Public Class ExpenseReportWorkflow : Inherits SequentialWorkflowActivity        Private evaluateExpenseReportAmount As IfElseActivity        Private ifNeedsLeadApproval As IfElseBranchActivity        Private elseNeedsManagerApproval As IfElseBranchActivity        Private invokeGetLeadApproval As CallExternalMethodActivity        Private invokeGetManagerApproval As CallExternalMethodActivity
        Private _amount As Integer = 0        Private _result As String        Private listenApproveReject As ListenActivity        Private eventDriven1 As EventDrivenActivity        Private eventDriven2 As EventDrivenActivity        Private WithEvents approveEvent As HandleExternalEventActivity        Private WithEvents rejectEvent As HandleExternalEventActivity        Public Property Amount() As Integer            Get                Return Me._amount            End Get            Set(ByVal value As Integer)                Me._amount = Value            End Set        End Property
        Public Property Result() As String            Get                Return _result            End Get            Set(ByVal value As String)                Me._result = Value            End Set        End Property
        Public Sub New()            InitializeComponent()        End Sub
        Private Sub InitializeComponent()            Me.CanModifyActivities = True
            Me.eventDriven1 = New System.Workflow.Activities.EventDrivenActivity()            Me.eventDriven2 = New System.Workflow.Activities.EventDrivenActivity()            Me.listenApproveReject = New System.Workflow.Activities.ListenActivity()            Me.approveEvent = New _                System.Workflow.Activities.HandleExternalEventActivity()            Me.rejectEvent = New System.Workflow.Activities.HandleExternalEventActivity()            Me.evaluateExpenseReportAmount = _                         New System.Workflow.Activities.IfElseActivity()            Me.ifNeedsLeadApproval = _                         New System.Workflow.Activities.IfElseBranchActivity()            Me.elseNeedsManagerApproval = _                         New System.Workflow.Activities.IfElseBranchActivity()            Me.invokeGetLeadApproval = _                         New System.Workflow.Activities.CallExternalMethodActivity()            Me.invokeGetManagerApproval = _                         New System.Workflow.Activities.CallExternalMethodActivity()            Dim ifElseLogicStatement As System.Workflow.Activities.CodeCondition = New _                        System.Workflow.Activities.CodeCondition()            Dim workflowparameterbinding1 As WorkflowParameterBinding = _                         New System.Workflow.ComponentModel.WorkflowParameterBinding()            Dim workflowparameterbinding2 As WorkflowParameterBinding = _                         New System.Workflow.ComponentModel.WorkflowParameterBinding()            '             ' EvaluateExpenseReportAmount            '             Me.evaluateExpenseReportAmount.Activities.Add(Me.ifNeedsLeadApproval)            Me.evaluateExpenseReportAmount.Activities.Add(Me.elseNeedsManagerApproval)            Me.evaluateExpenseReportAmount.Name = "evaluateExpenseReportAmount"            '             ' ifNeedsLeadApproval            '             Me.ifNeedsLeadApproval.Activities.Add(Me.invokeGetLeadApproval)
            AddHandler ifElseLogicStatement.Condition, AddressOf Me.DetermineApprovalContact            Me.ifNeedsLeadApproval.Condition = ifElseLogicStatement            Me.ifNeedsLeadApproval.Name = "ifNeedsLeadApproval"            '             ' elseNeedsManagerApproval            '             Me.elseNeedsManagerApproval.Activities.Add(Me.invokeGetManagerApproval)            Me.elseNeedsManagerApproval.Name = "elseNeedsManagerApproval"            '             ' invokeGetLeadApproval            '             Me.invokeGetLeadApproval.InterfaceType = GetType(IExpenseReportService)            Me.invokeGetLeadApproval.MethodName = "GetLeadApproval"            Me.invokeGetLeadApproval.Name = "invokeGetLeadApproval"            workflowparameterbinding1.ParameterName = "message"            workflowparameterbinding1.Value = "Lead approval needed"            Me.invokeGetLeadApproval.ParameterBindings.Add(workflowparameterbinding1)            '             ' invokeGetManagerApproval            '             Me.invokeGetManagerApproval.InterfaceType = GetType(IExpenseReportService)            Me.invokeGetManagerApproval.MethodName = "GetManagerApproval"            Me.invokeGetManagerApproval.Name = "invokeGetManagerApproval"            workflowparameterbinding2.ParameterName = "message"            workflowparameterbinding2.Value = "Manager approval needed"            Me.invokeGetManagerApproval.ParameterBindings.Add(workflowparameterbinding2)
            Me.eventDriven1.Activities.Add(Me.approveEvent)            Me.eventDriven1.Name = "eventDriven1"
            Me.eventDriven2.Activities.Add(Me.rejectEvent)            Me.eventDriven2.Name = "eventDriven3"
            Me.listenApproveReject.Activities.Add(Me.eventDriven1)            Me.listenApproveReject.Activities.Add(Me.eventDriven2)            Me.listenApproveReject.Name = "listenApproveReject"
            Me.approveEvent.EventName = "ExpenseReportApproved"            Me.approveEvent.InterfaceType = GetType(IExpenseReportService)            Me.approveEvent.Name = "approveEvent"
            Me.rejectEvent.EventName = "ExpenseReportRejected"            Me.rejectEvent.InterfaceType = GetType(IExpenseReportService)            Me.rejectEvent.Name = "rejectEvent"
            '             ' ExpenseReportWorkflow            '             Me.Activities.Add(Me.evaluateExpenseReportAmount)
            Me.Activities.Add(Me.listenApproveReject)            Me.Name = "ExpenseReportWorkflow"            Me.CanModifyActivities = False        End Sub
        Private Sub DetermineApprovalContact(ByVal sender As Object, _                  ByVal e As ConditionalEventArgs) 'Handles ifElseLogicStatement.Condition            If Me._amount < 1000 Then                e.Result = True            Else                e.Result = False            End If        End Sub
        Private Sub approveEvent_Invoked(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.ExternalDataEventArgs)
        End Sub
        Private Sub rejectEvent_Invoked(ByVal sender As System.Object, ByVal e As System.Workflow.Activities.ExternalDataEventArgs)
        End Sub    End ClassEnd Namespace
PROGRAM.VB
Imports Microsoft.VisualBasicImports SystemImports System.ComponentModelImports System.DrawingImports System.Windows.FormsImports System.Collections.GenericImports System.Workflow.RuntimeImports System.Workflow.Runtime.HostingImports System.Workflow.ActivitiesImports System.Threading
Namespace Microsoft.Samples.Workflow.Tutorials.SequentialWorkflow    Public Class MainForm : Inherits Form : Implements IExpenseReportService        Private label1 As System.Windows.Forms.Label        Private result As System.Windows.Forms.TextBox        Private label2 As System.Windows.Forms.Label        Private WithEvents submitButton As System.Windows.Forms.Button        Private approvalState As System.Windows.Forms.Label        Private WithEvents approveButton As System.Windows.Forms.Button        Private WithEvents rejectButton As System.Windows.Forms.Button        Private WithEvents amount As System.Windows.Forms.TextBox        Private panel1 As System.Windows.Forms.Panel
        Private components As System.ComponentModel.IContainer = Nothing
        Private Delegate Sub GetApprovalDelegate(ByVal message As String)        Public Event ExpenseReportApproved As EventHandler(Of ExternalDataEventArgs) _            Implements IExpenseReportService.ExpenseReportApproved        Public Event ExpenseReportRejected As EventHandler(Of ExternalDataEventArgs) _            Implements IExpenseReportService.ExpenseReportRejected
        Private workflowRuntime As WorkflowRuntime = Nothing        Private exchangeService As ExternalDataExchangeService = Nothing        Private workflowInstance As WorkflowInstance = Nothing
        Public Sub New()            InitializeComponent()
            ' Collapse approve/reject panel            Me.Height -= Me.panel1.Height
            Me.workflowRuntime = New WorkflowRuntime()            Me.exchangeService = New ExternalDataExchangeService()            workflowRuntime.AddService(exchangeService)            exchangeService.AddService(Me)            workflowRuntime.StartRuntime()
            AddHandler workflowRuntime.WorkflowCompleted, _                AddressOf Me.workflowRuntime_WorkflowCompleted        End Sub
        Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)            If disposing AndAlso (Not components Is Nothing) Then                components.Dispose()            End If            MyBase.Dispose(disposing)        End Sub
        Private Sub InitializeComponent()            Me.label1 = New System.Windows.Forms.Label()            Me.result = New System.Windows.Forms.TextBox()            Me.label2 = New System.Windows.Forms.Label()            Me.submitButton = New System.Windows.Forms.Button()            Me.approvalState = New System.Windows.Forms.Label()            Me.approveButton = New System.Windows.Forms.Button()            Me.rejectButton = New System.Windows.Forms.Button()            Me.amount = New System.Windows.Forms.TextBox()            Me.panel1 = New System.Windows.Forms.Panel()            Me.panel1.SuspendLayout()            Me.SuspendLayout()            '             ' label1            '             Me.label1.AutoSize = True            Me.label1.Location = New System.Drawing.Point(10, 13)            Me.label1.Name = "label1"            Me.label1.Size = New System.Drawing.Size(43, 13)            Me.label1.TabIndex = 1            Me.label1.Text = "Amount"            '             ' result            '             Me.result.Location = New System.Drawing.Point(13, 70)            Me.result.Name = "result"            Me.result.ReadOnly = True            Me.result.Size = New System.Drawing.Size(162, 20)            Me.result.TabIndex = 1            Me.result.TabStop = False            '             ' label2            '             Me.label2.AutoSize = True            Me.label2.Location = New System.Drawing.Point(10, 54)            Me.label2.Name = "label2"            Me.label2.Size = New System.Drawing.Size(37, 13)            Me.label2.TabIndex = 3            Me.label2.Text = "Result"            '             ' submitButton            '             Me.submitButton.Enabled = False            Me.submitButton.Location = New System.Drawing.Point(56, 95)            Me.submitButton.Name = "submitButton"            Me.submitButton.Size = New System.Drawing.Size(75, 23)            Me.submitButton.TabIndex = 2            Me.submitButton.Text = "Submit"            '             ' approvalState            '             Me.approvalState.AutoSize = True            Me.approvalState.Location = New System.Drawing.Point(10, 9)            Me.approvalState.Name = "approvalState"            Me.approvalState.Size = New System.Drawing.Size(49, 13)            Me.approvalState.TabIndex = 4            Me.approvalState.Text = "Approval"            '             ' approveButton            '             Me.approveButton.Enabled = False            Me.approveButton.Location = New System.Drawing.Point(11, 25)            Me.approveButton.Name = "approveButton"            Me.approveButton.Size = New System.Drawing.Size(75, 23)            Me.approveButton.TabIndex = 0            Me.approveButton.Text = "Approve"            '             ' rejectButton            '             Me.rejectButton.Enabled = False            Me.rejectButton.Location = New System.Drawing.Point(86, 25)            Me.rejectButton.Name = "rejectButton"            Me.rejectButton.Size = New System.Drawing.Size(75, 23)            Me.rejectButton.TabIndex = 1            Me.rejectButton.Text = "Reject"            '             ' amount            '             Me.amount.Location = New System.Drawing.Point(13, 29)            Me.amount.MaxLength = 9            Me.amount.Name = "amount"            Me.amount.Size = New System.Drawing.Size(162, 20)            Me.amount.TabIndex = 0            '             ' panel1            '             Me.panel1.Controls.Add(Me.approvalState)            Me.panel1.Controls.Add(Me.approveButton)            Me.panel1.Controls.Add(Me.rejectButton)            Me.panel1.Location = New System.Drawing.Point(7, 124)            Me.panel1.Name = "panel1"            Me.panel1.Size = New System.Drawing.Size(172, 66)            Me.panel1.TabIndex = 8            '             ' MainForm            '             Me.AcceptButton = Me.submitButton            Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F)            Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font            Me.ClientSize = New System.Drawing.Size(187, 201)            Me.Controls.Add(Me.result)            Me.Controls.Add(Me.label2)            Me.Controls.Add(Me.panel1)            Me.Controls.Add(Me.amount)            Me.Controls.Add(Me.submitButton)            Me.Controls.Add(Me.label1)            Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D            Me.MaximizeBox = False            Me.MinimizeBox = False            Me.Name = "MainForm"            Me.Text = "Simple Expense Report"            Me.panel1.ResumeLayout(False)            Me.panel1.PerformLayout()            Me.ResumeLayout(False)            Me.PerformLayout()
        End Sub
        Private Sub submitButton_Click(ByVal sender As Object, _                  ByVal e As EventArgs) Handles submitButton.Click            Dim type As Type = GetType(ExpenseReportWorkflow)
            ' Construct workflow parameters            Dim properties As Dictionary(Of String, Object) = _                New Dictionary(Of String, Object)()            properties.Add("Amount", Int32.Parse(Me.amount.Text))
            ' Start the workflow            workflowInstance = workflowRuntime.CreateWorkflow(type, properties)            workflowInstance.Start()        End Sub
        Private Sub workflowRuntime_WorkflowCompleted(ByVal sender As Object, _                  ByVal e As WorkflowCompletedEventArgs)            If Me.result.InvokeRequired Then                Me.result.Invoke(New EventHandler(Of WorkflowCompletedEventArgs) _                    (AddressOf Me.workflowRuntime_WorkflowCompleted), _                    New Object() {sender, e})            Else                Me.result.Text = e.OutputParameters("Result").ToString()
                ' Clear fields                Me.amount.Text = String.Empty
                ' Disable buttons                Me.approveButton.Enabled = False                Me.rejectButton.Enabled = False            End If        End Sub
        Private Sub approveButton_Click(ByVal sender As Object, ByVal e As EventArgs) _                  Handles approveButton.Click            ' Raise the ExpenseReportApproved event back to the workflow            RaiseEvent ExpenseReportApproved(Nothing, _                         New ExternalDataEventArgs(Me.workflowInstance.InstanceId))            Me.Height -= Me.panel1.Height            Me.submitButton.Enabled = True
        End Sub
        Private Sub rejectButton_Click(ByVal sender As Object, ByVal e As EventArgs) _                  Handles rejectButton.Click            ' Raise the ExpenseReportRejected event back to the workflow            RaiseEvent ExpenseReportRejected(Nothing, _                         New ExternalDataEventArgs(Me.workflowInstance.InstanceId))            Me.Height -= Me.panel1.Height            Me.submitButton.Enabled = True
        End Sub
#Region "IExpenseReportService Members"
        Public Sub GetLeadApproval(ByVal message As String) _                  Implements IExpenseReportService.GetLeadApproval            If Me.approvalState.InvokeRequired Then                Me.approvalState.Invoke(New GetApprovalDelegate _                    (AddressOf Me.GetLeadApproval), message)            Else                Me.approvalState.Text = message                Me.approveButton.Enabled = True                Me.rejectButton.Enabled = True
                ' expand the panel                Me.Height += Me.panel1.Height                Me.submitButton.Enabled = False            End If        End Sub
        Public Sub GetManagerApproval(ByVal message As String) _                  Implements IExpenseReportService.GetManagerApproval            If Me.approvalState.InvokeRequired Then                Me.approvalState.Invoke(New GetApprovalDelegate _        (AddressOf Me.GetManagerApproval), message)            Else                Me.approvalState.Text = message                Me.approveButton.Enabled = True                Me.rejectButton.Enabled = True
                ' expand the panel                Me.Height += Me.panel1.Height                Me.submitButton.Enabled = False            End If        End Sub
#End Region
        Private Sub amount_KeyPress(ByVal sender As Object, _                  ByVal e As KeyPressEventArgs) Handles amount.KeyPress            If (Not Char.IsControl(e.KeyChar)) AndAlso _                ((Not Char.IsDigit(e.KeyChar))) Then                e.KeyChar = Char.MinValue            End If        End Sub
        Private Sub amount_TextChanged(ByVal sender As Object, ByVal e As EventArgs) _                  Handles amount.TextChanged            submitButton.Enabled = amount.Text.Length > 0        End Sub    End Class
    Friend Class Program        Private Sub New()        End Sub        <STAThread()> _        Shared Sub Main()            Application.EnableVisualStyles()            Application.Run(New MainForm())        End Sub    End ClassEnd Namespace
 
Tom,
Thanks for all your help. I have solved the problem and now know more about the WF.
One more question is when we called an ExternalEvent, how can the event handle know the Instance's ID (in multi-instance environment)?
At the ApproveButton_Click routine:
RaiseEvent ExpenseReportApproved(Nothing, New ExternalDataEventArgs(Me.workflowInstance.InstanceId))
The code Me.workflowInstance.InstanceID pass only the id of the last workflow submitted, not the only who initial the event.
Many thanks.
Andy Ho
 
If you modify the approveEvent_Invoked and the rejectEvent_Invoked functions as below you'll get the message you were expecting
void approveEvent_Invoked(object sender, ExternalDataEventArgs e)
{
this._result = "Approved";
}
void rejectEvent_Invoked(object sender, ExternalDataEventArgs e)
{
this._result = "Rejected";
}

Related Links

Problems with Ownership, Timers etc
CustomPersistedService
Workflow and Development Modes
My workflow deriving from my own workflow base class - will it work?
Object To Object Map Activity
Distributed Transaction with WWF
MaxInstances WorkflowRuntime
Remote workflow tracking
callback trigger
Question about hosting
Context bindings wsdl generation
Use of HandleExternalEvent result in an IfElse activity
Custom Activity Designer
How to invoke rule set editor independently?
WebService and Persistence
Workflow Designer slow with numerous rules

Categories

MSDN
Windows Desktop Develo...
Windows Phone Dev Center
Data Platform Development
Microsoft ISV Communit...
Windows Embedded Standard
Visio 2010
Project Server
Bing Ads API: Development
Archived Forums C-D
Archived Forums N-R
Archived Forums Visual...
OneDrive Development
Internet of Things
Cortana
Visual Studio General ...
Visual Studio LightSwi...
Visual Studio Diagnost...
Application Insights (AI)
Windows Desktop Develo...
DirectShow Development
Windows Desktop Search...
Windows Desktop SDK
Development with the W...
Access for Developers
Outlook for Developers
Word for Developers
SharePoint 2010 - Setu...
SharePoint Legacy Vers...
Azure Data Factory
Windows Presentation F...
Team Foundation Server...
Team Foundation Server...
Team Foundation Server...
BizTalk Server RFID
BizTalk ESB Toolkit
XML, System.Xml, MSXML...
Internet Explorer Web ...
Microsoft Robotics - C...
Microsoft Robotics - C...
Visual Studio Smart De...
SQL Server Replication
Windows Embedded 8 Sta...
Standard 2009: Embedde...
Standard 2009: Misc
Windows Embedded Compa...
Windows Embedded Compa...
SQL Server 2012 Setup ...
Server Virtualization
Windows Live  Spaces: ...
MSDN Subscriptions Fee...
Orchard - Help and Sup...
Script Junkie Discussion
WebsitePanel - Develop...
Office Live Basics, Es...
SharePoint Server Prot...
Office XML, ODF, and B...
Project Server General...
Silverlight Installati...
Hosting and Streaming ...
Visual Studio & Silver...
Expression Studio with...
Expression Media
.NET Framework 4 setup...
ADO.NET Entity Framewo...
Azure Troubleshooting,...
Azure Startups
Charts & Reports in th...
Face Tracking – Kinect...
JScript for the .NET F...
Moderator Posting Only...
patterns & practices: ...
Phoenix
Silverlight (formerly ...
SQL Server 2014 In Azu...
SQL Server 2014 Report...
SQL Server 2014 Master...
Visual Basic Power Packs
Visual Studio 2008 (Pr...
Visual Studio Editor i...
Visual Studio LightSwi...
Windows Desktop Vista ...
Windows MultiPoint Mou...
Windows Presentation F...
Building Windows Store...
Windows Phone push not...
Cortana Skills Kit

Resources

Encrypt Message



code
soft
python
ios
c
html
jquery
cloud
mobile