Here’s a continuation of my list of coding tips and samples for the Infragistics NetAdvantage suite.  Part 1 dealt with the UltraGrid control, and I could actually devote Parts 2 through GigaMegaZillion® to the UltraGrid since there are so many facets to it.  I’ll return to the UltraGrid in future articles — today, for variety’s sake, let’s take a look at a considerably more narrowly focused tool, the UltraToolbarsManager.

(Incidentally, most of the the controls and classes in the Infragistics NetAdvantage suite were given the "Ultra" prefix awhile back, but the generally excellent NetAdvantage documentation still refers to them by their old "Win" prefix, and the namespaces have a prefix of UltraWin.  Go figure.  Anyway, in this article I’m using the Ultra prefix.)

The UltraToolbarsManager has a similar name to the .Net Framework’s ToolStripManager, but it plays a far more central role.  While the ToolStripManager is really just a toolstrip sidekick, relegated to merging and "rafting" toolbars and menubars, the UltraToolbarsManager lives up to its name — it owns all of the toolbars, menubar and context menus on the form, and all your code which accesses these objects needs to go through the manager. 

This makes it relatively easy to figure out the syntax for most toolbar-related properties and methods — just type the name of your UltraToolbarsManager control and let Intellisense guide you along.  It also makes it relatively easy to configure your toolbars and menubars at runtime rather than design time, since the code that creates a toolbar is almost identical to the code which creates a menubar or context menu.

Personally, I find the code easier to deal with than the UltraToolbarsManager designer, which is slow and surprisingly limited when it comes to the populating of your menus and toolbars. I tend to just drag an UltraToolbarsManager onto my form, let Infragistics automatically create the container you need to dock the toolbars and menubars, then add an empty menubar using the default settings. (The Infragistics designer applies some special settings for a menubar which aren’t worth coding from scratch). The form can then pass a reference to the UltraToolbarsManager object to the code that I describe below which configures things the way I want them.

As in Part 1, the code samples are based on the Windows Forms edition of "NetAdvantage for .NET 2007 Volume 1 CLR 2.0".  I’m pretty sure that they would work with more recent versions of NetAdvantage — if not, then stay tuned for "Infragistics NetAdvantage Tips – Part X: Dealing with Broken Compatibility after Upgrading"!

Here’s a generic initialization method that I use in every form in our application – it enforces certain properties that all our forms share:

public static void Infragistics_InitializeToolbarsManager(
    UltraToolbarsManager toolMgr)
{
        // set the transparency colour in toolbar button icons
        toolMgr.ImageTransparentColor = System.Drawing.Color.Magenta
        // don't allow the user to add or remove buttons
        toolMgr.ToolbarSettings.AllowCustomize = DefaultableBoolean.False;
        // don't allow the user to hide the toolbar completely
        toolMgr.ToolbarSettings.AllowHiding = DefaultableBoolean.False;
        // allow menubar and toolbar to be dragged onto same line
        toolMgr.LockToolbars = false;
        if (toolMgr.Toolbars.Count > 0)
            // allow menu bar and toolbar to be put on same line
            toolMgr.Toolbars[0].IsMainMenuBar = false;
}

All the form has to do is pass a reference to its UltraToolbarsManager control:

Infragistics_InitializeToolbarsManager(ultraToolbarsManager1)

The two main objects that are used to build a toolbar or menubar are the ButtonTool (toolbar buttons and menu entries) and PopupMenuTool (pulldown menus and context menus).  These are fairly similar to the .Net Framework’s ToolStripMenuItems — so similar, perhaps, that Infragistics deemed them unworthy of the honorific "Ultra".

There aren’t many interesting properties for the PopupMenuTool, so I just create them with their default settings:

popupMenu = new PopupMenuTool("File");
// the UltraToolbarsManager owns everything!
ultraToolbarsManager1.Tools.Add(popupMenu);
toolbar1.Tools.AddTool(popupMenu);

There are a number of useful settings for the ButtonTool, which can be an icon on a toolbar or menu entry.  Here’s a method that we use to create a ButtonTool regardless of where it is going to be located:

public static ButtonTool Infragistics_CreateButton(string strKey, string strCaption,
    object image, ToolDisplayStyle style, Shortcut shortcutKeys)
{

        ButtonTool button = new ButtonTool(strKey);
        button.SharedProps.DisplayStyle = style;
        try
        {
            // use same image for small and large toolbars
            button.SharedProps.AppearancesSmall.Appearance.Image = image;
            button.SharedProps.AppearancesLarge.Appearance.Image = image;
        }
        catch (Exception)
        {
            // image not found, so make it text only
            button.SharedProps.DisplayStyle = ToolDisplayStyle.TextOnlyAlways;
        }

        button.SharedProps.Caption = strCaption;
        button.SharedProps.Shortcut = shortcutKeys;

        return button;
}

The parameters passed to this method are self-explanatory except for ToolDisplayStyle: this is used to specify whether the button will be just an image, just text, or both.  One convenient setting is TextOnlyInMenus, which allows the same ButtonTool to appear as text if located in a menu and an image if located in a toolbar.  You might find that you use the same ButtonTool instance 3 times: once in the main menu, once in a toolbar and once in a context menu.

This "CreateButton" method becomes the basis for methods which populate toolbars, menubars and context menus.  For any of the three, the form passes an array of settings:

  1. button key
  2. button tooltip
  3. button image
  4. start of group indicator — if true, a separator line is added to the menu or toolbar before this item
  5. tool display style, as described above
  6. shortcut keys, if any

The method which applies these settings looks like this. (You’ll probably want to add code to allow the caller to use defaults for some settings, but I’ve omitted that code to keep things simple):

private static void addTools(UltraToolbarsManager toolMgr,
    ToolsCollection tools, object[,] buttons)
{

     for (int intColCounter = 0; intColCounter < = buttons.GetUpperBound(0); intColCounter++)
    {

        ButtonTool button = Infragistics_CreateButton((string)buttons[intColCounter, 0],
            (string)buttons[intColCounter, 1],
            buttons[intColCounter, 2], (ToolDisplayStyle)buttons[intColCounter, 4],
            (Shortcut)buttons[intColCounter, 5]);
        if (button != null)
        {
            toolMgr.Tools.Add(button);
            tools.AddTool(button.Key);
            // NOTE: first in group can't be set until the button is added to its parent
            tools[tools.Count - 1].InstanceProps.IsFirstInGroup = (bool)buttons[intColCounter, 3];
        }
    }
}

For example, to add buttons to a toolbar a form might call: 

Infragistics_InitializeToolBar(ultraToolbarsManager1, "MainToolbar",
    new object[,] {
    { "SaveButton", "Save", Images.Save1, true,
       ToolDisplayStyle.TextOnlyInMenus, Shortcut.CtrlS },
    { "RefreshButton", "Refresh", Images.Refresh, false,
       ToolDisplayStyle.TextOnlyInMenus, Shortcut.F5 },
    { "PrintButton", "Print", Images.Print1, false,
       ToolDisplayStyle.TextOnlyInMenus, Shortcut.CtrlP }
});

In the above code, "Images" is Resources File, added with Visual Studio’s Project->Add New Item menu, which contains all of our bitmaps and icons.

And here’s the code that creates that toolbar:

public static void Infragistics_InitializeToolBar(
    UltraToolbarsManager toolMgr,
    string strToolBarKey, object[,] buttons)
{

        // create the toolbar
        UltraToolbar toolBar = new UltraToolbar(strToolBarKey);
        toolMgr.Toolbars.AddToolbar(strToolBarKey);
        // create the toolbar buttons
        addTools(toolMgr, toolMgr.Toolbars[strToolBarKey].Tools, buttons);
}

Similarly, you can create a context menu by passing the same array to a slightly different method:

public static void Infragistics_InitializePopupMenu(
    UltraToolbarsManager toolMgr,
    string strMenuKey, object[,] buttons)
{
    // create the popup menu
    PopupMenuTool menu = new PopupMenuTool(strMenuKey);
    toolMgr.Tools.Add(menu);

    // create the toolbar buttons
    addTools(toolMgr, menu.Tools, buttons);

}

The form would use this method to create a context menu for a grid as follows:

    Infragistics_InitializePopupMenu(ultraToolbarsManager1, "GridContextMenu",
    new object[,] {
    { "Copy", "Copy", Images.Copy1, false,
      ToolDisplayStyle.ImageAndText, Shortcut.CtrlC },
    { "Paste", "Paste", Images.Paste1, false,
      ToolDisplayStyle.ImageAndText, Shortcut.CtrlV },
    { "Delete", "Delete", Images.Delete, false,
      ToolDisplayStyle.ImageAndText, Shortcut.Delete }
    });

    // set grid context menu
    ultraToolbarsManager1.SetContextMenuUltra(grdTest, "GridContextMenu");

Like a true micromanager, the UltraToolbarsManager insists on handling all the action, too.  When the user selects an option from a toolbar, menubar or context menu, it’s the UltraToolbarsManager’s ToolClick event that gets fired.  This makes it easy to use the same code to perform the same action regardless of how the user invoked it, , but sometimes you need to know what the context of the action is: for example, which grid does the user want to paste into. If the user selected the action using a context menu, you can use an event parameter to tell you which context menu:

if (e.Tool.OwningMenu != null)
    if (e.Tool.OwningMenu.Key == "GridContextMenu")
    {
         // oh, you mean the grid!
    }

But if the action was invoked using a shortcut key, the event parameters won’t help you. As a workaround, I check the form’s ActiveControl to get the context, but this is one area where I wouldn’t mind if Infragistics made my code obsolete in new versions.