Search code examples
wpfworkflow-foundation-4workflow-foundation

WF: Workflow Designer: List of InArgument added dynamically : How to get value during workflow execution


I have built a workflow designer that allows to enter a list of email addresses.Each email in the list needs to be an InArgument(Of String) so they can be individually edited/added using variables.

On my Activity, I have a property that is declared like so:

Public Property [To] As ObservableCollection(Of InArgument(Of String))

My designer is wired up and populating this collection properly.

However during the execution, I do not know how to get the run-time value for each InArgument that was added.

When we are executing the workflow and iterating for each InArgument added to the list, I attempted to get the value as shown below but that fails:

For Each toAddress As InArgument(Of String) In Me.To.ToList()
            Dim emailToAddress As String = toAddress.Get(_Context)          
Next

The error we get is “The argument of type '<type>' cannot be used. Make sure that it is declared on an activity” and type is a string in my case...

The error we get sort of make sense because we haven’t declared a property on the activity since it was added dynamically to the list and therefore cannot get the value using the syntax shown below:

The_Property_Name.Get(_Context)

Can someone help? I can't seem to find anything. Should I be doing a different approach?


Solution

  • I figured it out so I will answer my own question! All we need to do is explicitly add the collection items to the metadata by overriding CacheMetadata() method on the activity. This then makes it available to the workflow context.

    First we add them to the context:

       Protected Overrides Sub CacheMetadata(ByVal metadata As CodeActivityMetadata)
            MyBase.CacheMetadata(metadata)
    
            Dim i As Integer = 0
            For Each item As InArgument(Of String) In Me.To
                Dim runTimeArg As RuntimeArgument = New RuntimeArgument("TO" & i.ToString(), item.ArgumentType, item.Direction, False)
                metadata.Bind(item, runTimeArg)
                metadata.AddArgument(runTimeArg)
                i = i + 1
            Next
    
        End Sub
    

    Then when executing, we get the values like this

       For Each item As InArgument(Of String) In Me.To
                Dim email As String = _Context.GetValue(item)
            Next