Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Windows Workflow Foundation - Hosting the Designer
Mike Taulty's Blog

Mike's Badges

Follow on Twitter
View mike's profile on slideshare
Add to Technorati Favorites
CW Blog Awards

I've been shying away from this. I've heard from a few people that hosting the designer componentry that Windows Workflow Foundation provides is quite tricky and so I've generally been focusing on runtime bits and pieces and keeping my head down and hoping that I'd not get spotted hiding in the corner but you can only hide for so long :-)

I've been pouring over the designer hosting for only a few hours and the initial conclusion I've come to is that the designer hosting isn't hard per-se but;

  1. The designer can do a lot of things for you. It can do the following and probably a whole bunch more;
    1. Display a Workflow
    2. Perform commands (copy/paste/zoom/etc) on the items in the Workflow
    3. Work to generate properties and fields in classes as the user designs the Workflow
    4. Work to generate event handlers in classes as the user designs the Workflow
    5. Declaratively bind activity properties to each other
    6. Declaratively define rules
    7. Work to load/persist workflows/code and rules
    8. Provide interaction with the toolbox for dragging-dropping Activities
  2. The designer makes use of a bunch of componentry from the .NET Framework which most people (me included) aren't very familiar with.

There's an article that went onto MSDN a couple of months ago that's a life-saver when it comes to hosting the designer and it contains a sample but that sample is fairly large and it jumps straight into IDesignerHost and friends.

I'd suggest that you don't start by reading that article until you've read this one or revisited it - Create and Host Custom Designer with the .NET Framework V2.0

Update: I also found this article pretty useful as well.

Coming away from that article I know that;

  1. Components do not have a design/run mode. They have an associated designer component that does their design-time thing.
  2. In the simplest case, I need a DesignSurface to host designers and provide services to them.
  3. The DesignSurface provides an extensible bunch of services to design components
  4. One of the main services provided is the IDesignerHost service - can be used to create/destroy components.
  5. A DesignerLoader is usually plugged in so that a set of components for design can be loaded/stored to some kind of persistent storage.

With that tucked under my belt, I feel better prepared to go and tackle this Workflow specific article - Everything About Re-Hosting the Workflow Designer

I found that article a bit more of a struggle as it starts to throw in lots of functionality very quickly so I started to build some code instead and (in the first instance) I tried to build the simplest thing I could think of that might use the designer. I tried to build a form that will open up a XAML Workflow and display it in the designer.

I created a quick form with a one-option menu and a Panel on it. Then I need to spark up a DesignSurface which isn't too bad. Here, I can even tell it what the "root component" in the designer is going to be which saves me some typing later on;

designSurface = new DesignSurface(
  typeof(SequentialWorkflowActivity));

From the DesignSurface I can get an IDesignerHost so I grab hold of that;

designerHost = designSurface.GetService(
  typeof(IDesignerHost)) as IDesignerHost;

I can now ask IDesignerHost for a designer for that root component that we've added the type information for;

IRootDesigner rootDesigner = designerHost.GetDesigner(
  designerHost.RootComponent) as IRootDesigner;

From that IRootDesigner I can get hold of a View and, at this point, we hit Workflow specifics because we can cast this to a WorkflowView;

object view = rootDesigner.GetView(ViewTechnology.Default);
WorkflowView wfView = view as WorkflowView;

And finally, I can take that WorkflowView (it's a UserControl) and add it to my panel's Controls collection;

wfView.Dock = DockStyle.Fill; 
panel1.Controls.Add(wfView);

And I have something that functions in the sense of displaying the designer for a single SequentialWorkflowActivity on the screen.

 

I've uploaded the project at this point to Designer Part 1.

 

Now, if I want to move from where I've got a designer that can only display a single SequentialWorkflowActivity then I'm going to have to create my DesignSurface throughthe default constructor and load components into it later on as/when I load up a Workflow from a file.

If I want to go ahead and load a XAML Workflow from a file and I'm not concerned about code-behind, rules and so on then I can use something like;

private static Activity LoadWorkflowFromFile(string fileName)
{
  ActivityMarkupSerializer serializer = new ActivityMarkupSerializer();
  Activity activity = null;
  using (XmlReader reader = XmlReader.Create(fileName))
  {
    activity = serializer.Deserialize(reader) as Activity;
  }
  return (activity);
}

(note that the code doing the de-serialization here is going to need to be able to resolve any assemblies that Activities in the Workflow come from. This will work for the built-in Activities but you'd need to ensure that any custom Activities make themselves available (GAC, probing etc) so that they can be found as it the Workflow de-serialises).

And if I want to now display that Workflow in my designer then I need to go ahead and replace the piece of code I had earlier which hard-coded the type of a SequentialWorkflowActivity and add code to load all the Activities in the definition into the IDesignerHost;

private void AddActivityToDesigner(Activity rootActivity)
{
  // Add the activity itself...
  designerHost.Container.Add(rootActivity);
 
  // What if it has children?
  CompositeActivity compositeActivity = rootActivity as CompositeActivity; 
  if (compositeActivity != null)
  {
    foreach (Activity childActivity in compositeActivity.Activities)
    {
      // Recursing to make this simpler.
      AddActivityToDesigner(childActivity);
    }
  }
}

I've uploaded the project at this point to Designer Part 2, there's still a long way to go but at least I've got something on the screen - more to come as/when I manage to work it out.


Posted Fri, Aug 18 2006 10:08 AM by mtaulty

Comments

Mike Taulty's Blog wrote Windows Workflow Foundation - Hosting the Designer (Part 2)
on Mon, Aug 21 2006 2:02 AM
The cliffhanger of the previous post was that I'd managed to get a simple Workflow definition to load...
Mike Taulty's Blog wrote Workflow Designer Hosting - Summing Up (for now)
on Wed, Sep 6 2006 9:53 AM
I've been playing with the Workflow designer hosting for a little while, trying to get my head around...
Wilm’s FuzzyLogic » Blog Archive » New Windows Workflow Foundation Links wrote Wilm’s FuzzyLogic » Blog Archive » New Windows Workflow Foundation Links
on Wed, Feb 14 2007 4:49 AM
(C) Mike Taulty, 2009. All rights reserved. The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems