Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Windows Workflow Designer Hosting - Part 6, Menus

Blogs

Mike Taulty's Blog

Elsewhere

Following on from this post and always with reference to this article...

So far, whilst I've been able to drag Activities from the Toolbox to the design surface and then drag them around on the design surface I've not got any menu functionality so I thought I'd have a bash at adding that. In particular, I've found it a bit limiting not to be able to delete any Activities that I've added.

The first thing I did here was to have a look at the WorkflowMenuCommands class and the myriad of commands that are on there. Some seem to be commands such as WorkflowMenuCommands.Delete whereas others sound like menus to me, e.g. WorkflowMenuCommands.DesignerActionsMenu.

The article does a good job of explaining that you need a MenuCommandService plugged in for context menus to work so I went off to build one of those.

Whenever I've got to write some kind of plug-in I like to derive from the base-class, override everything to call the base class implementation and then set a bunch of breakpoints and sit in the debugger watching what happens with my new plug-in class.

So, I do that and run up my designer again and load my Workflow definition and my breakpoints start firing and I can see that the AddCommand method keeps getting called by the WorkflowView which looks (thanks again to Reflector) to use a class called CommandSet in order to add a bunch of commands such as Zoom commands, Navigation commands, Layout commands.

Once that has happened (I had to kill the breakpoint in AddCommand as there's a few calls that go by) I see a call to my MenuCommandService's Verbs property looking for a set of DesignerVerbs that it supports. This is as a result of the first selection change within the designer and I can see the base class here coming back with a list of verbs such as "Generate Handlers", "Bind Selected Properties", "Move Left", "Move Right" and so on. I can see this set of verbs being requested around 3-4 times every time my selection changes in the designer.

Once the designer is on the screen, if I right mouse on the design surface then I can see the ShowContextMenu call being made and the base class does nothing for me there.

So, that playing around has been quite useful and it ties in with what the main article tells me and I can build an override of ShowContextMenu;

    public override void ShowContextMenu(CommandID menuID, int x, int y)
    {

The thing I puzzled with a bit on this was where I was to get the names of the menu options from. For example, WorkflowMenuCommands.Delete is a CommandID that I can get hold of but where do I get the text to put onto the menu option? In the end, I hard-coded it and built a little list of "known menus" into my class to store these. I'm sure there's another way of doing it but it's what I did. I have 4 known menus - the zoom menu, the pan menu, the page layout menu and the selection menu and I store details about their respective options in arrays such as;

    private static InternalMenuItem[] selectionMenuItems = new InternalMenuItem[] {
      new InternalMenuItem(WorkflowMenuCommands.Cut, "Cut"),
      new InternalMenuItem(WorkflowMenuCommands.Copy, "Copy"),
      new InternalMenuItem(WorkflowMenuCommands.Paste, "Paste"),
      new InternalMenuItem(WorkflowMenuCommands.Delete, "Delete")
    };
 

and then those arrays I add into a dictionary so they can be looked up from ShowContextMenu as in;

 

  public override void ShowContextMenu(CommandID menuID, int x, int y)
    {
      // Should really cache these menus rather than keep rebuilding them.
      ContextMenu ctxMenu = null;

      if (menuID == WorkflowMenuCommands.SelectionMenu)
      {
        ctxMenu = AddDesignerVerbsToContextMenu();
      }

      // See if we can find the menu items in our little internal
      // store.
      InternalMenuItem[] items;

      if (knownMenus.TryGetValue(menuID.ID, out items))
      {
        if (ctxMenu == null)
        {
          ctxMenu = new ContextMenu();
        }

        for (int i = 0; i < items.Length; i++)
        {
          MenuItem item = new MenuItem(items[i].Label);
          item.Tag = items[i].CmdId;

          MenuCommand mc = this.FindCommand(items[i].CmdId);
          item.Enabled = mc.Enabled;
          item.Checked = mc.Checked;

          item.Click += new EventHandler(OnMenuItemClick);
          ctxMenu.MenuItems.Add(item);
        }
      }

      if (ctxMenu != null)
      {
        WorkflowView view = (WorkflowView)GetService(
          typeof(WorkflowView));

        ctxMenu.Show(view, view.PointToClient(new Point(x, y)));
      }
    }

The only menu that gets special treatment is the SelectionMenu where we also add in designer "verbs" that can be performed.

This is all pretty much like the sample and I found that the menuing functionality is one of the pieces of the sample that's easiest to understand although I did struggle to locate one or two menu options in the enumerations (particularly the menu option on the "Pan" menu that says "Go back to the standard layout" - haven't found this one yet).

Once I had this up and running, I played around with it a little and found that the menu options seemed to work ok - I had a bit of a "red herring" with copy-and-paste in that it seems to end up throwing a lot of (caught) exceptions in the course of its operation - not quite sure yet whether something is broken or not here but I have the same results with copy-and-paste in the sample.

So, menus are "basically" working - here's the project file with where I'm up to at this point. There's still a lot more to do and I might try saving changes that have been made to the Workflow next...


Posted Sun, Sep 3 2006 3:23 PM by mtaulty

Comments

Mike Taulty's Blog wrote Windows Workflow Designer Hosting - Saving
on Tue, Sep 5 2006 7:14 AM
Following on from this post&amp;nbsp;and always with reference to this article... I've moved along in Workflow...
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&#8217;s FuzzyLogic &raquo; Blog Archive &raquo; New Windows Workflow Foundation Links
on Wed, Feb 14 2007 4:49 AM