none
How to reference the correct workbook from a control in a ribbon callback RRS feed

  • Question

  • There doesn't seem to be a way to find out to which workbook a ribbon callback refers. We need to do this, as when a 2nd workbook becomes active, the ribbon controls need to be updated to reflect the state of the workbook which is in the same window as the control.

    A similar (if no the same) question was asked over a year ago, but received no answer. So here's another attempt to find out how to resolve this problem with the ribbon in Excel 2013 (and PowerPoint for that matter).

    We are using Excel 2013 SP1 (15.0.4659.1000) 32bit. The problem manifests itself in both native C++ COM addins and VSTO/C#.

    Summary:

    1. Place a <group> or other control in the AddIns tab in the ribbon. Add a callback in the xml to dynamically load the label using a callback, eg getLabel="GetMyLabel".
    2. In the ribbon class add the callback, which sets the label to be the name of the workbook associated with the ribbon control.
      public string GetMyLabel(Office.IRibbonControl control)
      {
          Excel.Window myWindow = control.Context;
          Excel.Workbook myWorkbook = window.Parent;
          return ("My Label: " + myWorkbook.Name);
      }
    3. Invalidate the RibbonUI each time when the workbook is activated, using the Application.WorkBookActivate() event.

    Expected:

    • With a single Workbook open, the group label shows the name of the workbook.
    • With two or more workbooks open, the group label should show the name of the workbook that is in the same window.

    Actual:

    • The case with a single workbook is correct
    • The case with multiple workbooks is failing. With two workbooks open, when I activate the inactive workbook (by placing the mouse in one of the cells), the group labels for both workbook now display the name of the newly activated workbook. When I activate the first workbook, both group labels switch back to the name of the first workbook.

    Happy to post up VSTO project for validation.





    • Edited by OfficeAddInner Sunday, November 23, 2014 5:11 AM fix syntax error
    Sunday, November 23, 2014 5:05 AM

All replies

  • Hello,

    The architecture of the Fluent UI is designed that way. There is no way to keep separate values for different windows. You can only update the value depending on the context handling the Activate events of the Window - Workbook.Activate or Worksheet.Activate events in case of Excel.

    You can read more about the Fluent UI in the following series of articles:

    Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)

    Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)

    Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

    Sunday, November 23, 2014 2:40 PM
  • If I understand correctly, what you are saying is that with the Excel (and PowerPoint 2013) there is no way for each SDI ribbon to reflect the state of the workbook to which it belongs.

    It is OK when there is a single workbook open, or each is open in it's own process.

    However, when there are multiple workbooks open (in a shared process), then the ribbon for each open workbook can only reflect the status of the active workbook.

    This is contrary to the native ribbon operation in Excel 2013. If I set the font for a cell in one workbook, and then use a different font in a second workbook. Each ribbon displays the font selected in for that workbook. One window can show Calibri, and the other Comic Sans.

    The question is how to replicate this for the Fluent UI, so our custom controls can reflect the state of the workbook.

    The MSDN documentation for the IRibbonControl.Context property says that it "represents the active window containing the Ribbon user interface that triggers a callback procedure." This could do with some clarification/correction. We see that it is also being called for the control in non-active windows, but refers to the active workbook.

    Sunday, November 23, 2014 10:43 PM
  • Hi OfficeAddInner,

    >>The case with multiple workbooks is failing. With two workbooks open, when I activate the inactive workbook (by placing the mouse in one of the cells), the group labels for both workbook now display the name of the newly activated workbook. When I activate the first workbook, both group labels switch back to the name of the first workbook.<<

    If you want to the keep the name of group based on the workbook, it is not necessary to invalidate the ribbon UI. If I dont't invalidate the ribbon in Workbook active event, the code works well for me as figure below:

    Did I miss anything?

    Regards & Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.



    Monday, November 24, 2014 6:29 AM
    Moderator
  • > If I understand correctly, what you are saying is that with the Excel (and PowerPoint 2013) there is no way for each SDI ribbon to reflect the state of the workbook to which it belongs.

    You are on the wrong avenue. The only possible way is to use callbacks and the Ivalidate/InvalidateControl methods of the IRibbonUI interface.

    Monday, November 24, 2014 7:05 AM
  • @Fei,

    thanks for trying. This is a complicated issue and I appreciate your help.

    We thought about not using the Invalidate() methods. The example I used was probably oversimplified, in that it just shows the workbook's name.

    In reality, we want to display a property that can be changed (say by other ribbon controls), and the ribbon needs refreshing when the property changes. We use the Invalidate() method to trigger the refresh.

    Is there another way to refresh the  controls other than using Invalidate()?

    Monday, November 24, 2014 6:01 PM
  • @Eugene,

    I think I agree with you.

    > The only possible way is to use callbacks and the Ivalidate/InvalidateControl methods of the IRibbonUI interface.

    This is our understanding as well.

    The issue is that with the 2013 SDI when you call Invalidate, it seems to refresh the ribbon of each workbook. The problem we are facing is that when you are processing the callback, it seems there is no way of accessing the workbook for that ribbon.

    Our testing has shown that the control's context always refers to the active workbook, so you can't get the properties for the inactive workbooks, and therefore the ribbons for the inactive workbooks will reflect the properties of the active workbook. :-(

    We are looking for a way to resolve the above problem. In a ribbon UI callback, how do we navigate to the workbook for the control in the callback?

    Monday, November 24, 2014 6:10 PM
  • Some further information:

    It seems that there is also something strange happening, depending upon where you click in the workbook to activate it.

    I have two workbooks open, with the custom UI as described before. When the workbook is activated, the ribbon is invalidated. There is a callback on the ribbon control which updates its label to show the name of the workbook to which it belongs.

    There seems to be two different operating modes:

    1. If I activate the background workbook by clicking the mouse in the ribbon area, the callback is only called once. The label of the newly activated window is updated. There is no callback for the deactivated window. In my test example, it means that the control for each ribbon displays the name workbook associated with that ribbon (which is what we want).
    2. However, if I activate the background workbook by clicking in the cell area, the callback is called twice: once for each of the ribbon (the newly activated, and the other workbook). In both cases, the context of the control refers to the active workbook. In my test example, it means that the control for both workbooks displays the name of the activate workwork. (Not what we want).

    A similar test was repeated with MS Word 2013. It follows the behaviour described in #1 above

    Tuesday, November 25, 2014 8:08 AM
  • I'd suggest opening a support case.
    Saturday, November 29, 2014 4:19 PM
  • Hi OfficeAddInner,

    Since the issue is complex, I'm trying to involve some senior engineers into this issue and it will take some time. Your patience will be greatly appreciated.

    Sorry for any inconvenience and have a nice day!

    Regards & Fei


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, December 1, 2014 9:31 AM
    Moderator
  • Hi  OfficeAddInner

    Thanks for sharing the sample repro file. We have checked this issue and able to reproduce as explained. 

    As you know SDI was introduced in 2013 on wards and supporting multiple instances as well. when we try this repro under multiple instances, then do not see an issue where as by default we see the label update happens. We do not know whether this is working as designed or some issue with the design. 

    At this point I am under the impression that this need deep-down analysis. Because of its complexity, your question falls into the paid support category which requires a more in-depth level of support.  If the support engineer determines that the issue is the result of a bug the service request will be a no-charge case and you won't be charged. Please visit the below link to see the various paid support options that are available to better meet your needs. http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone

    Mahesh

    Wednesday, December 17, 2014 12:32 AM
  • Hi OfficeAddInner,

    I am hoping you can share whether or not you found a resolution.  We have just completed the implementation of an add-in for which we did development in Excel 2010, and were rather surprised to discover the differences during testing with Excel 2013.  We have several custom ribbon controls that need to reflect a workbook-level state. I was researching and came across your post.

    Any insights are greatly appreciated.

    Amelia


    Thursday, May 7, 2015 3:32 PM
  • Hi Amelia,

    we still have no solution, and the problem still exists in the Office 2016 beta which we tested about a month or two ago.

    We had some follow up with a Microsoft Support Engineer, but it was never resolved :-(

    After some investigation, the Microsoft Support Engineer was able to reproduce similar behaviour with native ribbon controls. That is, the values displayed on the non-active workbooks reflected those of the active workbook.

    My memory is fading, but I think that the problem was due to additional (superfluous) callbacks being made into non-active workbooks. This doesn't occur in Word, but does occur in Excel/PowerPoint depending on where the user click in the application window to activate the workbook/presentation.

    Monday, September 7, 2015 4:08 AM
  • I am also seeing this issue also.  It doesn't occur with Word or with Office 2010.  It does happen with Office 2013 and Office 2016, both 32-bit and 64-bit.  It does not happen with my VBA add-ins, only with the VSTO add-ins.

    The issue is that the ribbon on the Excel window behind the active Excel window is modified when the ribbon on the active window is updated.  If there are three workbooks open the last window is not modified, only the front and second workbooks are updated.

    Microsoft has documented that in the SDI implementation starting with Office 2013, each open workbook gets its own instance of the ribbon, along with all the controls it contains. This means that separate events should be generated for the controls on each ribbon.

    However, there are no ribbon events generated for any window other than the activate window, but the second window with a different workbook is updated.  The window for the front workbook (and thus the front ribbon) is obtained using the control.Context field, similar the code in the original post in this thread.

    Is there any known workaround yet?

    Thursday, May 12, 2016 2:59 AM
  • Has anybody found a possible method for getting this to work yet?
    Thursday, July 14, 2016 1:13 PM
  • It's just a bug in Excel - see the whole discussion here: https://social.msdn.microsoft.com/Forums/office/en-US/118884c9-f699-4d13-b446-e4548b9a1933/ribbon-invalidation-in-sdi-excel-2013-callback-affect-wrong-window?forum=exceldev

    To get this fixed, you will probably need to find (or to be) a major Microsoft client who cares about the issue and then raise this through the sales channel.

    -Gvert

    Sunday, July 17, 2016 7:39 PM
  • This really is a mess, as my company's add-in heavily customizes the ribbon and this bug is noticeably affecting the performance of Excel 2016 as it's double-refreshing the two front-most Excel windows every time we invalidate the active window.

    Microsoft really needs to address this ASAP...

    Monday, July 2, 2018 9:13 PM
  • Hi Mahesh,

    Has Microsoft made any progress in resolving this issue since this comment on it last December.

    The issue is also discussed at https://social.msdn.microsoft.com/Forums/office/en-US/118884c9-f699-4d13-b446-e4548b9a1933/ribbon-invalidation-in-sdi-excel-2013-callback-affect-wrong-window?forum=exceldev&prof=required, and there's now no doubt that it's a bug in Excel 2013 and Excel 2016.

    This bug materially negatively affects the performance of add-ins which heavily customize the ribbon, reflecting very poorly upon both Microsoft and us developers, so it warrants priority attention.

    Please provide an update ASAP.

    Thanks.

    Monday, July 2, 2018 9:16 PM
  • Hi OfficeAddInner - did you by chance end up getting any comfort from Microsoft about when this issue will be resolved?

    Monday, July 2, 2018 9:19 PM
  • The IRibbon.Control.context does provide a handle to a window, which is supposed to be the window that the ribbon is on.  However, it is actually always just the active window, so not helpful.  A straight bug that will probably never get fixed.

    You do get call backs for each ribbon instance, so can set them to different values.  But there is no clean way to know which one is which.

    I am happy to help Microsoft improve their products by providing good bug reports.  But I have never seen a response that is meaningful.  I doubt if anyone has ever had any comfort from Microsoft about any issue unless they were connected to a major client.
    • Edited by aberglas Wednesday, March 27, 2019 1:55 AM Control.context.
    Wednesday, March 27, 2019 1:37 AM
  • Not correct.  You get a callback for each ribbon instance and can set them to different values.  There is just no way to know which instance is relevant because the IRibbonControl.context value is broken.

    • Edited by aberglas Wednesday, March 27, 2019 1:59 AM
    Wednesday, March 27, 2019 1:58 AM