Friday, June 15, 2007

Activity properties in Windows Workflow

I initially thought Windows Workflow was horrendously complicated, needlessly so. I've since realised that it's just exceedingly extensible but one problem is that there aren't a great deal of internet resources to search through to find the answer. No surprise I guess since this is pretty new technology. So I've decided to add some little tidbits. I'll present a few very short posts about a very small subset of the functionality, a kind of Windows Workflow for dummies. Given that I'm a dummy myself, I am perfectly placed to do this I reckon. Of course since I'm still learning all about WF, these posts may be incomplete or plain wrong.

So first up, adding a property to a custom activity. Properties in WF don't work like properties in normal .NET classes, they are based around dependency properties, which are properties that can be attached to any class deriving from DependencyObject. All activities inherit from DependencyObject so they can use dependency properties. I believe dependency properties must be used when you want to let your workflow designers be able to bind their properties together. Normal properties would have no way of knowing how to update other bound properties when their value had changed.

What is probably worth mentioning at this point is that WPF also uses dependency properties and dependency objects. They look very similar to the WF ones, but they are defined in a different place (System.Windows for WPF, System.Workflow.ComponentModel for WF) so I can only assume there are some subtle differences between the two.

Anyway, here's some code for a simple WF property.

    public static DependencyProperty FormProperty = DependencyProperty.Register("Form", typeof(string), typeof(UserActivity));
    
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [Browsable(true)]
    [Description("The form to be displayed when the user initiates the activity")]
    public string Form
    {
      get
      {
        return ((string)(base.GetValue(UserActivity.FormProperty)));
      }
      set
      {
        base.SetValue(UserActivity.FormProperty, value);
      }
    }

So we have a custom activity called UserActivity with a property called Form. It looks like a normal property except the getters and setters use the GetValue and SetValue methods defined in the DependencyObject class. Beyond that all we need to do is register the dependency property. Once that is done, the property should appear just like any other in your workflow.

3 comments:

Anonymous said...

thanks for this post, i really learned from it. Im trying the custom property to a state activity and the code that you posted does not work with that kind of activity. Any idea about this.. Is it possible to have custom property for a state activity. Thanks

Selmo

Doogal Bell said...

Hi Selmo

I've added properties to custom state activities. When you say it doesn't work do you mean it doesn't compile or it fails at runtime? What error do you get?

SELMO said...

Sorry bell im so careless with my code, i notice that if you named your dependency property to a different one with your custom property it will not compile. Like if you name ur custom prop with "MyPath" you should name ur dependency property with "MyPathProperty". Thanks bell