An Hierarchical CAB WorkItem Activation Service

The application I’m currently working on has a rather complex UI. It’s something like two tabbed work spaces and an outlook-like work space, that make one workspace by itself, that can have several instances inside another tabbed workspace, that can have several instances inside another tabbed workspace. Imagine something like Visual Studio, inside a tab.

Each work space is controlled by its own work item and the same goes to every smart part.

With a UI like this, the work item activation service supplied by the CAB is of no use for me because I need to know what is the active work item at various levels.

What I came up with to solve my problem is the following implementation of the work item activation service:

public class HierarchicalWorkItemActivationService : IWorkItemActivationService
{
    private object syncroot = new object();
    private WorkItem activeWorkItem;
    private WorkItem hostingWorkItem;

    public HierarchicalWorkItemActivationService()
    {
    }

    [ServiceDependency]
    public WorkItem HostingWorkItem
    {
        set
        {
            Debug.Assert(value != null);
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            Debug.Assert(this.hostingWorkItem == null);
            if (this.hostingWorkItem != null)
            {
                throw new InvalidOperationException("HostingWorkItem already set.");
            }
            this.hostingWorkItem = value;
        }
    }

    public void ChangeStatus(WorkItem item)
    {
        lock (syncroot)
        {
            if (item == this.hostingWorkItem)
            {
                WorkItem hostingParentWorkItem = this.hostingWorkItem.Parent;
                if (hostingParentWorkItem != null)
                {
                    IWorkItemActivationService parentWorkItemActivationService = hostingParentWorkItem.Services.Get<IWorkItemActivationService>();
                    if (parentWorkItemActivationService != null)
                    {
                        parentWorkItemActivationService.ChangeStatus(this.hostingWorkItem);
                    }
                }
            }
            else
            {
                if (item.Status == WorkItemStatus.Active)
                {
                    if (item != this.activeWorkItem)
                    {
                        if (this.activeWorkItem != null && this.activeWorkItem.Status != WorkItemStatus.Terminated)
                        {
                            this.activeWorkItem.Deactivate();

                            // If the activeWorkItem is still active deactivates the item and aborts.
                            if (this.activeWorkItem.Status == WorkItemStatus.Active)
                            {
                                item.Deactivate();
                                return;
                            }
                        }
                        this.activeWorkItem = item;
                    }
                }
            }
        }
    }
}

6 thoughts on “An Hierarchical CAB WorkItem Activation Service”

  1. Suppose you have a WorkItem wiA and you want to track its active child work items (wiA1, wiA2, wiA3, …).

    To do that, you must register this service in wiA and the activation of its children will be controlled by this service independently of the other work items.

  2. This works great! All your posts on CAB/SCSF are very informative, hope to see more in the future, thanks Paulo!

  3. Your blogs are great and need a word of appreciation. Keep up the good work.

    What I understand from the case discussed here is the need to have a hierarchy of Workitems to be tracked as Active at the same time?

    I have two queries to know the need for the same:

    1. Why would we need to have a workitem for every Workspace and Smart Part that we create? As per the MS P&P we are supposed to create a workitem per UseCase, and the workspaces which are generally shared between the modules are added to the rootworkitem.

    2. In a hierarchy of Workitems like

    Root->Child1->GrandChild2->GrandGrandChild3 if GrandGrandChild3 is Active, we can comprehend the complete hierarchy to be Active? How different is this scenario?

    Hope I am not asking too silly queries……as I have just jumped into SCSF and am relatively new.

  4. Thank you for your kind words, Parameshwaran.

    Yes. Take Outlook as an example. You have the left Outlook bar where you have one item selected. Each of that items have items themselves that might be selected (a folder in the folder list, a day or week in the calendar, etc.) and for a particular forlder you have one e-mail selected.

    1. There’s no mandatory need to have one work item for every smart part, but nothing forbides you from having just one smart part for work item.

    2. With the CAB/SCSF provided activation service you have only one active work item. So, if GrandGrandChild3 is active no other work item is active, not even Root, Child1 or GrandChild2 are active.

    Feel free to ask more questions, but there’s an active community and team members at http://www.codeplex.com/smartclient/Project/ListForums.aspx.

Comments are closed.