Some Useful Workflow Links
The Windows SDK contains a lot more information on the WinFx technologies, and some cool samples to help you get started.
There are some holes though. In particular, we've been making use of validators for our custom activities to ensure that they're initialised correctly before a workflow is run. There's a good post here on this to help fill in the blanks in the current documentation.
The basic process for use is as you might expect if you've build .Net controls before:
- Create a validator class inheriting from the 'ActivityValidator' type.
- Enter the validation logic.
- Register the validator with your custom activity using the [Validator] attribute.
Pretty straightforward. One tiny piece of knowledge that may escape you from the example (it did me), is that once the validator is attached to the custom activity then of course you can't compile the activity as the validation fails (remember this is design-time as well as run-time validation). The innocuous line of code you need is to check whether the activity is taking part in a workflow (i.e. if parent != null) prior to running the validation logic. This way you can compile, use and validate at the correct times. Caught me out. D'oh!
As I say, in general, the activity authoring experience is the same as building other .Net controls, so I probably should have figured it out. (For example, it's not mentioned in the docs, but to make a property readonly, you'd just use the [ReadOnly] attribute as you would elsewhere). What I really need is Chris Sells to right a book aimed at WF in the same way as his excellent Win Forms book, which made the fog clear for me in that area.
Next up is some cunning code for dynamic properties. We came across a scenario where inputs into one custom activity would need to be hooked up variously as inputs and outputs into other activities. These were essentially collections of files so we used a collection to input these into the custom activity. BUT, you then can't use the collection directly to bind to properties on other collections. What you need are dynamic properties which, after being entered as a collection, become visible to other activities for binding. I hope I've explained that enough. Anyway, this post is a bit sparse, but the code attached to it certainly isn't and does just the trick!