I have an ArcMap 10.0 add-in in which I have a button that the user can place (using the Customize dialog in ArcMap) on any toolbar including user-created toolbars as well as standard ones or even 3rd party ones. They could even put multiple instances of this button on the same or many toolbars (what can I say, some people can be crazy).

I have some code I need to run on each ICommandItem instance (to set its FaceID property, see this question if interested) wrapping this button command.

How can I reliably find each of these instances?

Currently I only set the first (and only) one returned by ICommandBars.Find, leaving the rest alone. Not the worst thing in the world, but less than ideal.

I thought I had a lead with this snippet (List ArcMap Visible Toolbars) but this only lists standard ArcMap toolbars (those in the 'ESRI Mx Command Bars' component category in the registry). From that I could iterate over each command item in each toolbar.

This approach could work if I could get it to list all toolbars including user-defined ones (which are not in any category as far as I can tell), and, admittedly less-importantly, 3rd party ones (which may or may not always be in the same category used by the snippet, I'm not sure).

I found this crusty old unanswered post from 2003 on the ESRI forums asking how to find user toolbars: "Detect user defined toolbars programmatically" -- don't you just hate dead ends?

Lastly I found an answer in this post, "looping through all commandbars", (from our own GIS.se member Kirk Kuykendall, no less) which looks promising but I can't see how to translate the CreateObject call to .NET, and crucially, it doesn't look like you can actually get an ICommandBar reference from its items.

Any pointers would be greatly appreciated.

2 Answers 2


I think you are already on the right track. You should use the CommandBars property of IDocument to get a collection of all the tool bars available to a document such as you have seen in the "List ArcMap Visible Toolbars" snippet. But that snippet is coming at things from slightly different angle as it is finding command bars based on items in a category.

I think in your case you should just call CommandBars to get the collection of CommandBars (effectively unfiltered) and then iterate over the collection to get each ICommandBar item. Then you can call the Find method on each ICommandBar to find your ICommandItem instance and then do whatever you need to it.

  • Two problems with this. 1) I don't think you can iterate over the CommandBars collection, it only offers a Find method. See also: forums.esri.com/Thread.asp?c=93&f=1170&t=259154
    – blah238
    Aug 29, 2012 at 23:49
  • 1
    2) ICommandBar.Find only returns the first matching command item. However you CAN iterate over the Items in a command bar using array syntax -- I think.
    – blah238
    Aug 29, 2012 at 23:50

IToolBarDef.GetItemInfo method got me to loop all ICommandItem objects.

I should say that this method is prettly slow :(

First of all, We need a temporary class that implements IItemDef, since Arcobjects did not allow me to create a new IItemDef object.

public class ScrapClass : IItemDef
    #region IItemDef Members

    public bool Group { get; set; }
    public string ID { get; set; }
    public int SubType { get; set; }


Below code is an improvement of the ESRI snippet..

public List<string> ListArcMapVisibleToolbars(IApplication application)
    List<string> toolbarList = new List<string>();

    //Only work with ArcMap application types, not ArcCatalog, ArcGlobe, ArcToolBox, etc.
    if (!(application is ESRI.ArcGIS.ArcMapUI.IMxApplication))
        return null;

    // Set up GUID object for 'ESRI Mx Command Bars' component category
    UID uid_MxCommandBars = new UIDClass();
    uid_MxCommandBars.Value = (System.Object)("{B56A7C4A-83D4-11d2-A2E9-080009B6F22B}"); // Explict Cast

    // Set up the category factory.
    ICategoryFactory categoryFactory = new CategoryFactoryClass();
    categoryFactory.CategoryID = uid_MxCommandBars;

    IDocument document = application.Document;

    // Go through each member of the category, and if it is a toolbar try to find it in the document
    object object_ComponentCategory = categoryFactory.CreateNext();
    ICommandBars commandBars = document.CommandBars;

    while (object_ComponentCategory != null)
        if (object_ComponentCategory is IToolBarDef)
            IToolBarDef toolbarDef = (IToolBarDef)object_ComponentCategory; //Explicit Cast

            Debug.Print("Toolbar - " + toolbarDef.Name);
            for (int i = 0; i < toolbarDef.ItemCount; i++)
                ScrapClass itemdef = new ScrapClass();
                toolbarDef.GetItemInfo(i, itemdef);
                //print the UID of commandItem
                UID uid = new UIDClass();
                uid.Value = itemdef.ID.ToString();
                ICommandItem commandItem = commandBars.Find(uid, false, false);
                if (commandItem != null)
                    Debug.Print(i + "," +  commandItem.Name + "," + commandItem.Category);

        object_ComponentCategory = categoryFactory.CreateNext();
    return toolbarList;
  • It looks like this suffers the same pitfalls as I mentioned before: 1. User-defined and add-in toolbars cannot be found through component categories AFAICT. 2. ICommandbars.Find only returns the first instance of the item, not the one on the current toolbar. And yes it is very slow :( Thank you though!
    – blah238
    Nov 28, 2012 at 18:47
  • @blah238 - as i see, it is finding items under custom extensions and user defined toolbars..and it definitely finds the UIDs of of all the commanditems in all toolbars..
    – vinayan
    Nov 29, 2012 at 1:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.