Minimal code to create an image from a workflow

I have been experimenting a bit with hosting the workflow designer. Unfortunately the sample provided, while it works is kind of hard to get started with if you are not already familiar with the way designers work in Visual Studio. So I decided to create the minimal code to create an image of a workflow, something quite useful if you are going to with an ASP.NET site to monitor you workflows. One caveat to be aware of is that the code needs to run under a thread with an STA ApartmentState. If not you will receive errors messages that the DragDrop registration did not succeed while creating the WorkflowView.


 


The code is pretty simple. Basically it uses a standard System.ComponentModel.Design.DesignSurface and System.Workflow.ComponentModel.Design.WorkflowView type to work with the workflow. To load the workflow a custom WorkflowDesignerLoader subclass is required to do the actual loading. No big deal. If you are using a State Workflow you need to override the OnEndLoad function to load the .layout file and use the LoadDesignerLayout function to add it to the image generated.


 


Imports System.ComponentModel.Design
Imports System.ComponentModel.Design.Serialization
Imports System.Drawing.Imaging
Imports System.Workflow.Activities
Imports System.Workflow.ComponentModel
Imports System.Workflow.ComponentModel.Design
 
Module Module1
    Sub Main()
        Dim workflow AsNew SequentialWorkflowActivity
        workflow.Activities.Add(New DelayActivity())
 
        Dim loader AsNew WorkflowLoader(workflow)
        Dim surface AsNew DesignSurface
        surface.BeginLoad(loader)
        Dim view AsNew WorkflowView(CType(surface, IServiceProvider))
        view.SaveWorkflowImage(“workflow.png”, ImageFormat.Png)
 
        Process.Start(“workflow.png”)
    EndSub
EndModule
 
 
PublicClass WorkflowLoader
    Inherits WorkflowDesignerLoader
 
    Private _workflowDefinition As Activity
 
    SubNew(ByVal workflowDefinition As Activity)
        _workflowDefinition = workflowDefinition
    EndSub
 
    ProtectedOverridesSub PerformLoad(ByVal serializationManager As IDesignerSerializationManager)
        MyBase.PerformLoad(serializationManager)
 
        Dim designerHost As IDesignerHost = Me.GetService(GetType(IDesignerHost))
        Dim allActivities As List(Of Activity) = WorkflowUtils.GetAllActivities(_workflowDefinition)
 
        ForEach item As Activity In allActivities
            designerHost.Container.Add(item, item.QualifiedName)
        Next
    EndSub
 
    PublicOverridesReadOnlyProperty FileName() AsString
        Get
            Return“”
        EndGet
    EndProperty
 
    PublicOverridesFunction GetFileReader(ByVal filePath AsString) As System.IO.TextReader
        ThrowNew NotSupportedException()
    EndFunction
 
    PublicOverridesFunction GetFileWriter(ByVal filePath AsString) As System.IO.TextWriter
        ThrowNew NotSupportedException()
    EndFunction
EndClass
 


Enjoy!


 


Update: Continued here.


 




6 thoughts on “Minimal code to create an image from a workflow

  1. Great job!
    i’ve converted your code to C# and i’m testing it.
    btw, is there a way to change the workflow “label” (the “Sequential Workflow” text at the top of the image)?

  2. I don’t think there is without editing the image. This basically just makes an image of what the WF designer looks like. And the designer is limited in the ways you can modify its appearance.

    Maurice

  3. Such a pitty.. I’d like to use it to generate some diagrams from empty classes, just to get the image. I’m gonna follow your advice and try a workaround now (maybe cutting the image or placing something over the label).
    Thanks for your reply!

    Rico.

  4. Thanks for the article. I tried to use this code and display the image in a windows app and it worked but I was not able to display this on a web form. I am getting an overflow exception where the WorkFlowView is being used.
    Can you please tell me if I’m missing some thing ?

    thanks
    kiran

  5. Hi Kiran,

    I have used this to display an image on a website so I surprised you are getting an overflow exception. The only problem I ran into was the different threading model ASP.NET uses as compared to VS so I had to spin up a new thread and do the work in there.

    Maurice

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>