I have a custom activity, with a single in argument which is a string. However, rather than allow the designer to enter an arbitrary string, I want the designer to be presented with a Combobox with the list of options, the options are dynamic and are loaded from a database into a List<> collection.
My problem is I have no clue how to bind the Combobox in the designer to this list and have the selection set to the in argument of the activity. Visually I have the activity designer working, it is just this one step.
Normally, I would write the activity with a
property
rather than anInArgument
. This simplifies the scenario:(here ValidOptions is some Collection property on your ActivityDesigner class. MyStringProperty is some public get/set/ property on the underlying activity such as:
)
The problem you will have if you add
InArgument
to the mix is that the string values from the combo box cannot be directly assigned to aModelItem
expectingInArgument<string>
. This is fixable using a customIValueConverter
in your binding.The previous answers are helpful but were not enough for me. Eventually I found a terrific article from 2012, in Microsoft's .Net 4.5 Developer Guide: Binding a custom activity property to a designer control. That article was almost the full answer - except for a minor bug in the custom converter class, and a major flaw: that technique will save a value from the ComboBox, but it will not restore it when you re-open your workflow.
Microsoft's Ron Jacobs has another answer for custom activity designers. I ended up combining the two to get a working solution.
Custom Designer
The
ModelToObjectValueConverter
was an incredibly helpful resource, allowing me to skip creating my ownIValueConverter
. In theObjectDataProvider
you see me loading a list of strings by calling a static method,People.GetPeople()
. The ComboBox binds to that provider as the item source, but binds the selected value to the Person property on the custom Activity (below)Custom Code Activity
Note that this uses a property rather than an InArgument, which makes binding the ComboBox easier.
Workflow
Now the custom activity,
CodeActivity1
, can be dragged onto a workflow. When you make a selection, the selected value will appear in the properties pane. Save the workflow. Close and re-open. The previously-selected value will persist as desired.One way to solve it is to define your own ComboBoxEditor which derives from UITypeEditor. Expose the collection you want to bind this combobox in the activity class and decorate your bindable property in Activity class with following attribute :
Also in the custom comboboxEditor you will have to modify your EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) method to get the collection and bind it to the combobox.