none
Event for RibbonTab click in Excel Addin RRS feed

  • Question

  • Hi,

    I am working on an Excel Addin. I am using VS 2008 and Excel 2007.
    Currently my addin gets loaded on opening of Excel. Since i have a dropdown in the Ribbon, even that gets loaded on openeing of Excel. And since that loading of dropdown takes time, i wanted to change this behavior. I wanted to load my Addin on click of the
    Ribbon Tab. For this i wanted to know how to fire the event on click of Ribbon Tab.

    Usually ThisAddIn_Startup() is the method that's fired first when excel is opened. But i want to call this method in the event of Click of Ribbon Tab. Is this possible?

    basically i want to capture click event of Ribbon Tab.

    Can someone please help me on this.

    Regards,
    Shailendra
    • Edited by Shailendra_G Tuesday, January 13, 2009 4:24 PM added
    Tuesday, January 13, 2009 3:40 PM

Answers

  • Hi ,

    Here's a short sample for you, as Cindy mentioned there's no "click event" for a Ribbon tab, so we need to pick Dropdown list instead.

    The idea is when Excel starts we add a button in Dropdown list, if user click the button, then refresh the Dropdown list,fill it with the real data, and also hide the button at same time:

    <?xml version="1.0" encoding="UTF-8"?>  
    <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="Ribbon_Load">  
      <ribbon> 
        <tabs > 
          <tab idMso="TabAddIns"  > 
            <group id="MyGroup"   
                   label="My Group">  
              <dropDown id="myDropDown" onAction="dropDownAction" getEnabled="dropDownGetEnabled" getItemLabel="ItemLabel" getItemCount="ItemCount"  > 
     
                <button id="mybutton" label="Button" onAction ="ReDraw" showImage="false" getVisible="getButtonVisible"/>  
                  
              </dropDown> 
                  
                  
                
            </group> 
          </tab> 
        </tabs> 
      </ribbon> 
    </customUI> 
     
     
      bool ButtonVisible = true;  
            int itemCount = 0;  
            public void Ribbon_Load(Office.IRibbonUI ribbonUI)  
            {  
                this.ribbon = ribbonUI;  
                  
            }  
            public void ReDraw(Office.IRibbonControl RibbonControl)  
            {  
                this.ButtonVisible = false;  
                this.itemCount = 9;  
                ribbon.InvalidateControl("myDropDown");  
                ribbon.InvalidateControl("mybutton");  
            }  
            public void dropDownAction(Microsoft.Office.Core.IRibbonControl control, string selectedId, int selectedIndex)  
            {  
     
            }  
            public bool dropDownGetEnabled(Office.IRibbonControl RibbonControl)  
            {  
                return true;  
            }  
            public string ItemLabel(Office.IRibbonControl control, int index)  
            {  
                 
                return "Item " + index.ToString();  
            }  
            public int ItemCount(Office.IRibbonControl control)  
            {  
     
                return this.itemCount;  
            }  
            public bool getButtonVisible(Office.IRibbonControl RibbonControl)  
            {  
                return this.ButtonVisible;  
            } 
    For more information about InvalidateControl method :
    http://msdn.microsoft.com/en-us/library/aa433553.aspx

    Thanks
    • Marked as answer by Shailendra_G Wednesday, January 28, 2009 8:06 PM
    Wednesday, January 21, 2009 6:51 AM
  • Hi Shailendra

    You know, it's a bit difficult for us, juggling two separate conversations about the same thing. The discussions diverged fairly early on, so I let them run, thinking you'd finally decided on one or the other approaches. The two cannot be combined, you must use the one, or the other.

    If you decide to dynamically load the dropdown content at any arbitrary point in time (rather than when the Ribbon loads), then you don't populate the list in your XML. Instead, you assign callbacks to the dropdown (I mentioned getItem in an earlier reply) and those callbacks fill the list. Tim gave you a complete example in his answer of January 21. Study that, including the documentation link.


    Cindy Meister, VSTO/Word MVP
    • Marked as answer by Shailendra_G Wednesday, January 28, 2009 8:06 PM
    Wednesday, January 28, 2009 5:27 PM
    Moderator

All replies

  • There is no "click event" for a Ribbon tab.
     
    There was another discussion here, recently, where the developer was complaining that he wanted the dropdown list already populated on startup because loading it dynamically took too much time the first time the user clicked the button. IOW, the exact opposite problem you're having.

    So, rather than definting the list of items statically in your Ribbon XML, use the "getItem" set of attributes to define callbacks that populate the list dynamically. These apparently fire the first time the user enters the list.
    Cindy Meister, VSTO/Word MVP
    • Marked as answer by Tim Li Monday, January 19, 2009 3:07 AM
    • Unmarked as answer by Shailendra_G Tuesday, January 20, 2009 6:02 PM
    Thursday, January 15, 2009 8:24 AM
    Moderator
  • Hi Cindy,

    Can you please point me to any sample of doing this.

    Shailendra
    Tuesday, January 20, 2009 6:02 PM
  • Hi ,

    Here's a short sample for you, as Cindy mentioned there's no "click event" for a Ribbon tab, so we need to pick Dropdown list instead.

    The idea is when Excel starts we add a button in Dropdown list, if user click the button, then refresh the Dropdown list,fill it with the real data, and also hide the button at same time:

    <?xml version="1.0" encoding="UTF-8"?>  
    <customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="Ribbon_Load">  
      <ribbon> 
        <tabs > 
          <tab idMso="TabAddIns"  > 
            <group id="MyGroup"   
                   label="My Group">  
              <dropDown id="myDropDown" onAction="dropDownAction" getEnabled="dropDownGetEnabled" getItemLabel="ItemLabel" getItemCount="ItemCount"  > 
     
                <button id="mybutton" label="Button" onAction ="ReDraw" showImage="false" getVisible="getButtonVisible"/>  
                  
              </dropDown> 
                  
                  
                
            </group> 
          </tab> 
        </tabs> 
      </ribbon> 
    </customUI> 
     
     
      bool ButtonVisible = true;  
            int itemCount = 0;  
            public void Ribbon_Load(Office.IRibbonUI ribbonUI)  
            {  
                this.ribbon = ribbonUI;  
                  
            }  
            public void ReDraw(Office.IRibbonControl RibbonControl)  
            {  
                this.ButtonVisible = false;  
                this.itemCount = 9;  
                ribbon.InvalidateControl("myDropDown");  
                ribbon.InvalidateControl("mybutton");  
            }  
            public void dropDownAction(Microsoft.Office.Core.IRibbonControl control, string selectedId, int selectedIndex)  
            {  
     
            }  
            public bool dropDownGetEnabled(Office.IRibbonControl RibbonControl)  
            {  
                return true;  
            }  
            public string ItemLabel(Office.IRibbonControl control, int index)  
            {  
                 
                return "Item " + index.ToString();  
            }  
            public int ItemCount(Office.IRibbonControl control)  
            {  
     
                return this.itemCount;  
            }  
            public bool getButtonVisible(Office.IRibbonControl RibbonControl)  
            {  
                return this.ButtonVisible;  
            } 
    For more information about InvalidateControl method :
    http://msdn.microsoft.com/en-us/library/aa433553.aspx

    Thanks
    • Marked as answer by Shailendra_G Wednesday, January 28, 2009 8:06 PM
    Wednesday, January 21, 2009 6:51 AM
  • Thanks Tim ... i will try that out.

    Shailendra

    Friday, January 23, 2009 7:19 PM
  • Hi Tim,

    While i was trying your suggestion, i came accross a doubt.

    Following is the way i am trying to populate my drop down and this happens on the loading of the ribbon.

    public string GetCustomUI(string ribbonID)  
            {  
                reportPane = Globals.ThisAddIn.ReportPane;  
                availableServices = Catalog.GetAvailableReports();  
                string resourceText = string.Empty;  
                resourceText = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><customUI onLoad=\"Ribbon_Load\" xmlns=\"http://schemas.microsoft.com/office/2006/01/customui\">";  
                resourceText = resourceText + "<commands>";  
                resourceText = resourceText + "<command idMso=\"SheetRowsInsert\" onAction=\"myRowInsert\" />";  
                resourceText = resourceText + "<command idMso=\"SheetColumnsInsert\" onAction=\"myColumnInsert\" />";  
                resourceText = resourceText + "<command idMso=\"SheetRowsDelete\" onAction=\"myRowDelete\" />";  
                resourceText = resourceText + "<command idMso=\"SheetColumnsDelete\" onAction=\"myColumnDelete\" />";  
                resourceText = resourceText + "</commands>";  
                resourceText = resourceText + "<ribbon>";  
                resourceText = resourceText + "<tabs>";  
                resourceText = resourceText + "<tab id=\"tabNTrust\" label=\"Trust\">";  
                resourceText = resourceText + "<group id=\"grpAvailableDataServices\" label=\"Available Data Services\">";  
                resourceText = resourceText + "<dropDown id=\"DataServiceDropDown\" onAction=\"DropDownSelectionChanged\" label=\"Choose a Data Service:\" showImage=\"false\">";  
                if (availableServices != null)  
                {  
                    int serviceCount = availableServices.Services.Count;  
                    for (int i = 0; i < serviceCount; ++i)  
                    {  
                        resourceText = resourceText + "<item label=\"" + availableServices.Services[i].Name + "\" supertip=\"" + availableServices.Services[i].Help + "\" id=\"__id" + (i + 1) + "\" />";  
                    }  
                }  
                resourceText = resourceText + "</dropDown>";  
                resourceText = resourceText + "<toggleButton id=\"tgbShowTaskPane\" onAction=\"tgbShowTaskPane_Click\" label=\"Show Data Services\" showImage=\"false\" />";  
                resourceText = resourceText + "</group>";  
                resourceText = resourceText + "</tab>";  
                resourceText = resourceText + "</tabs>";  
                resourceText = resourceText + "</ribbon>";  
                resourceText = resourceText + "</customUI>";  
                return resourceText;  
            } 

    I am generating my Ribbon XML dynamically.

    So if i had to try your code, how would i stop the dropdown from loading in the first place, i.e during the load of the ribbon.

    And then how would i populate it again with data on click of the button.

    Can you please tell me how to proceed on this?

    Thanks,

    Shailendra

     

    Wednesday, January 28, 2009 4:09 PM
  • Hi Shailendra

    You know, it's a bit difficult for us, juggling two separate conversations about the same thing. The discussions diverged fairly early on, so I let them run, thinking you'd finally decided on one or the other approaches. The two cannot be combined, you must use the one, or the other.

    If you decide to dynamically load the dropdown content at any arbitrary point in time (rather than when the Ribbon loads), then you don't populate the list in your XML. Instead, you assign callbacks to the dropdown (I mentioned getItem in an earlier reply) and those callbacks fill the list. Tim gave you a complete example in his answer of January 21. Study that, including the documentation link.


    Cindy Meister, VSTO/Word MVP
    • Marked as answer by Shailendra_G Wednesday, January 28, 2009 8:06 PM
    Wednesday, January 28, 2009 5:27 PM
    Moderator
  • Thanks for the suggestion Cindy.

    I think i was not clear in presenting my problem, but i got the solution from your suggestion.

    Yes, currently i had to load it dynamically, but because of performance issue, i had to change it to loading arbitarily.

    And thats why i had to start a new thread with this problem.

    But now after implementing Tim's solution, i was able to do it.

    Thanks for the quick reply.

    Shailendra

    Wednesday, January 28, 2009 8:06 PM
  • Hi Tim,

    thanks a lot for your sample that shows a way to "simulate" an OnShow-Event for some ribbon tab.
    I've tried this out and it seems to work - somtimes.

    My problem: I am trying to detect if the backstage view is activated. So I added a button with an event handler:

      <backstage>
        <button id="myButton1" visible="true" onAction="OnActionBackstageButton" />
      </backstage>
     
    
    public void OnActionBackstageButton(IRibbonControl control)
    {
       //Some action triggered here
    }
    

    When I enter the backstage view, my event is triggered - but only one time!
    So I decided to invalidate the button in the event handler: 

    public void OnActionBackstageButton(IRibbonControl control) {    this.ribbon.InvalidateControl("myButton1");
    }

    But this doesn't work. Can you help me???

    Thanks in advance,
    Jörg from germany

    Monday, March 2, 2015 9:54 AM
  • I'm following exactly same steps but by button click doesn't fire up

    Steps I followed

    1. On Ribbon I clicked ExportRibbionToXML

    2. This generated the ribbon.cs and xml file

    3. Copy pasted Tim's code :)

    

    Ribbon.cs

    4. Started the project and clicked the dropdown list but it never fired any event its empty.

    What am i missing ?

    Thanks for the help

    S

    Wednesday, March 22, 2017 12:06 PM