I thought I would share some wrapper classes that I use in just about all of my Visio add-ins for managing the state of my custom menu and toolbar items. These wrapper classes were a collaborative effort between me and the developers at Visimation, Inc.
Before Visio began using CommandBars as the supported method for customizing the Visio menus and toolbars, state management was much easier. The UIObject allowed you to scope your custom UI to the Application object or the Document object. Applying your custom UI to a specific document object prevented your UI from being accessible from other open documents. Visio handled this for you as you switched between documents.
CommandBars is now the preferred method for customizing the UI in Visio and has been for some time. CommandBars provide additional functionality but CommandBar customizations cannot be scoped to a specific Document object, they are only available from the Application object. Because of this, your custom UI changes are available no matter what document is active.
This is fairly easy to workaround and a typical method is to have each function that is executed based on the clicked CommandBarControl to first perform a check to see if that function should execute based on the active document or the current selection. What you really want is to have your menu and toolbar items automatically enable and disable based on the active document or the content of the current selection, and these wrapper classes provide that for you.
The architecture is simple, wrap each CommandBarButton object that you create and tell the wrapper how it should treat the wrapped CommandBarButton, i.e. AlwaysActive, DocumentActive, or SelectionActive. The wrapper handles updating the Enabled property of each wrapped CommandBarButton instance based on this setting. In addition to this setting you can also define a callback method that each wrapper can call to allow you to set the Enabled property with your own custom rules, i.e. the active document must contain a User cell that has the value of “MyCustomDocument”.
In the attachment you will see the UIMgr class that is used to manage all the objects for the UI customizations. The Startup and Shutdown methods from the ThisAddIn class make calls to the UIMgr class to add or remove our customizations.
I like to remove my UI customizations in the event that a user chooses to unload my add-ins from the list of managed add-in via the Trust Center dialog. This is typically overlooked and I see a lot of orphaned UI customizations because someone has unloaded an add-in or they have uninstalled an add-in.
VisioCommandBarItem wrapper classes
To use these wrappers all you have to do is create your CommandBarButton or CommandBarPopUp object as you normally would. Then you create an instance of the corresponding wrapper class, VisioCommandBarButton or VisioCommandBarPopUp and set the ButtonEnabled argument to specify how you want the Enabled state to be managed.
Each wrapper instance manages the Enabled state for the wrapped object using some events from the Visio.Application object. These events trigger an update to the Enabled state if needed.
The AddUI method in the UIMgr class demonstrates how to create a button for each of the ButtonEnabled states.
After you download this source you should be able to compile it and run it. You will need VS 2008, VSTO 3.0, and Visio 2007. Visio 2007 will also need to have .NET Programmability Support installed (PIA).
Feel free to add the UIMgr.cs and the VisioCommandBars.cs source files to your own project. In most cases all you will need to do is change the AddUI method to add your specific CommandBarButtons or PopUps.
Click here to download the sample VSTO based add-in that demonstrates how these wrapper classes are used, along with the full source to the wrapper classes.