How to Write a Toolbox Item Component for Custom Workflow Activity

In previous posts I discussed about Writing a Custom Workflow Activity and Writing a Validator for a Custom Workflow Component.  In this post I want to talk about writing a Toolbox Item component for a custom workflow activity and implement it for my sample activity.

A Toolbox Item component helps you to manage your activity instance when it's being added to workflow.  For example you can use this component to set some initial values for your activity properties or to add some child activities to a composite activity by default.

Like validator component, adding a toolbox component to a custom workflow activity consists of two steps:

ActivityToolboxItem  is a class that is located at System.Workflow.ComponentModel.Design namespace.  To add a Toolbox Item component to your custom workflow activity you need to add a new class to your project and inherit this class from ActivityToolboxItem base class.  Note that this class must be Serializable.  Then you need to write public constructor for this class and derive it from base class constructor.  Also it's necessary to write a private constructor and call Deserialize() method from base class in order to be able to build this component.

The main step and the heart of our code is when you override CreateComponentsCore() function.  This function gets an IDesignerHost component as parameter and returns an array of IComponents.  You simply need to return an array of activities that you want to add to workflow.  Writing such a component needs four references to System.Workflow.ComponentModel.Design, System.Runtime.Serialization, System.ComponentModel and System.ComponentModel.Design namespaces and you also need to add a reference to System.Drawing for your project.

Let's update my sample custom workflow to see above theories in action.  I want to update my activity and add a Toolbox Item component to set two initial values for its properties when user drags and drops this activity into his workflow.  First I create a CustomActivityToolboxItem class, mark it as Serializable and derive it from ActivityToolboxItem.  After that I write its constructors and methods (described above) and add my logic to overridden CreateComponentsCore() function.  After creating an instance of my CustomActivity, I set its properties and return an array of IComponents which contains only one member.

using System;

using System.Collections.Generic;

using System.Text;

using System.Workflow.ComponentModel.Design;

using System.Runtime.Serialization;

using System.ComponentModel;

using System.ComponentModel.Design;

 

namespace CustomActivitySample

{

    [Serializable]

    internal sealed class CustomActivityToolboxItem : ActivityToolboxItem

    {

        public CustomActivityToolboxItem(Type type)

            : base(type)

        {

        }

 

        private CustomActivityToolboxItem(SerializationInfo info,

            StreamingContext context)

        {

            base.Deserialize(info, context);

        }

 

        protected override IComponent[] CreateComponentsCore(IDesignerHost host)

        {

            CustomActivity activity = new CustomActivity();

            activity.Path = @"C:\file.txt";

            activity.Text = "Tomato :-D";

 

            return new IComponent[] { activity };

        }

    }

}

Well, now I add a reference to System.ComponentModel in my CustomActivity class and add a new ToolboxItem attribute to it.  This attribute gets the type of my Toolbox Item component as parameter.

using System;

using System.Collections.Generic;

using System.Text;

using System.Workflow;

using System.Workflow.Activities;

using System.Workflow.Runtime;

using System.Workflow.ComponentModel;

using System.Workflow.ComponentModel.Design;

using System.IO;

using System.Workflow.ComponentModel.Compiler;

using System.ComponentModel;

 

 

namespace CustomActivitySample

{

    [ActivityValidator(typeof(CustomActivityValidator))]

    [ToolboxItem(typeof(CustomActivityToolboxItem))]

    public class CustomActivity : Activity

    {

Ok, I compile this Class Library into an assembly and add this custom activity to my toolbox again.  If I drag this activity and drop it into my sequence workflow and check its properties and look at its properties.  My default values are there.

 

Setting default values or adding default children to composite activities are two common applications for toolbox item components.  There are other applications that you may find based on your needs.

Now playing: Richard Clayderman - The Poet And I

[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.

4 Comments : 02.04.07

Feedbacks

 avatar
#1
DotNetKicks.com
02.04.2007 @ 9:22 AM
You've been kicked (a good thing) - Trackback from DotNetKicks.com
 avatar
#2
Keyvan Nayyeri
02.12.2007 @ 10:53 PM
So far I've discussed about these topics about writing a custom workflow activity: How to Write a Custom
 avatar
#3
Martin
12.06.2007 @ 1:38 AM
Hello Richard, I have developed a custom workflow activity, and successfully used it in a workflow. Now I need to update the activity, and change the workflow accordingly. I'm finding Visual Studio is confusing in picking up the changes to my upgraded component. In one project it picks up the changes. In another it clings to the old activity, but I don't know how or why. Can you give me any tips? It's like the old version is cached somewhere, thus blocking the new version which is successfully reporting it's version in the toolbox. Thanks alot Martin
 avatar
#4
Danijelr
07.08.2008 @ 4:47 AM

Martin, In properties you might want to set the project to Build in Release not debug.

Leave a Comment