Adding Variables, Expressions and Bindings Programmatically
I am assuming we already know how to add activities on to the designer surface dynamically using the designer programmatic APIs. If not please take a look here.
Another variation of the ask is we want to add variables and arguments to our activities/workflows at design time dynamically. Example scenario: If a specific activity is drag dropped and its input type is same as the output of the previous activity on the workflow, bind the input of this newly added activity to the output of the other activity.
Yes, we would need a variable here so that we can bind it to the InArgument and the OutArgument of the activities to link them for data flow.
How do we go about doing it:
const string myStrName = "myStrName";
Variable<string> mySimpleVar= new Variable<string> { Name = myStrName };
myItem.Parent.Properties["Variables"].Collection.Add(mySimpleVar);
This was just about adding a variable. How about providing a default value to the variable. Lets see how we go about doing that:
mySimpleVar.Default = new VisualBasicValue<string>
{
ExpressionText = "\"Kushal\"",
};
Next step/hurdle – What if the variable is of some user defined type? We would then need to add a namespace declaration as part of the Imports section in the Workflow
Example: If you want to create a variable of type fooClass defined in assembly – fooAssembly.dll and namespace - foo, we would go about as follows:
static string requiredAssemblyName =
typeof(foo.fooClass).Assembly.GetName().Name;
static string requiredNamespace = typeof(foo.fooClass).Namespace;
VisualBasicSettings vbSettings = new VisualBasicSettings();
vbSettings.ImportReferences.Add(new VisualBasicImportReference
{
Assembly = requiredAssemblyName,
Import = requiredNamespace
});
mySimpleVar.Default = new VisualBasicValue<foo.fooClass>
{
ExpressionText = "new foo.fooClass()",
Settings = vbSettings
};
Now the rest is about the binding of the outArgument of one activity to the inArgument of the other activity. For example:
Argument myArg =
Argument.Create(typeof(foo.fooClass),ArgumentDirection.In);
myArg.Expression = new VisualBasicValue<foo.fooClass>
{
ExpressionText = myStrName
};
this.ModelItem.Properties["Response"].SetValue(myArg);
where “Response” is an InArgument for my activity and myStrName is the variable we just created above.
We follow the similar model for the outArgument and you have programmatically completed binding the output of one activity to the input of another activity. One change though is that for the outArgument expression assignment you need to use a VisualBasicReference instead of a VisualBasicValue.
Thanks,
Kushal.
Comments
Anonymous
March 10, 2010
I tried your sample code and adding variable to In argument is successful. But when I tried the same with an Out Argument, I got an error when serializing the workflow using XamlServices. Could you please show an example on how to bind an variable to an out argument? Thanks.Anonymous
March 19, 2010
Use following method to set compiler settings: VisualBasic.SetSettings(vb, vbSettings);Anonymous
June 22, 2010
Hi Kushal I was trying to autobind when an activty with an inArgument<string> is added into a ForEachActivity<String>. The issue is that the ForEach<string> allows the user to name the item variable. But I can't for the life of me find the variable name in the forEach's modelItem. If I had this then the binding would be as simple as creating an expression of inArgument<string> with the item varaible name, but instead I'm stuck. The ForEach<string> activities "Body" property (ActivityAction<T>) shows as null in the model item. Am I being an idiot here, or is there another way to do this. Cheers, JasonAnonymous
June 24, 2010
There is no Settings property defined in VisualBasicValue.Anonymous
December 05, 2011
This is exactly what i'm looking for. But where should I put those code in? In my custom activity code? I think I need to put it inside my custom activity code but I can't find Model Item.Anonymous
December 02, 2012
The comment has been removed