none
Why is RibbonMenu nesting limited to 5 levels? And how can I override this? RRS feed

  • Question

  • Hi there!

    In an Excel 2010 Addin we programmatically populate a multi-level RibbonMenu with items from a database. However, it seems impossible to display a RibbonMenu having more than five levels. (Some) Clients get a runtime exception stating that a maximum of only 5 nest levels is supported (verbatim: "Maximal 5 geschachtelte Menüs sind zulässig."). After dismissing the dialog window, the menu shows and is functional, but any menu items deeper than five levels are missing and some items on levels <= 5 are disabled (e.g. RibbonMenus missing their level-5-RibbonButtons).

    • Why is there a nesting limit?
    • Is there anything we can do to override this limit? The figure '5' in the message looks suspicious, like there is some magic int value to be set somewhere...
    • Are there any other controls that can be used to display a multi-level nested menu inside an Excel ribbon?

    Thanks in advance and best regards,
    Thomas


    • Edited by tvoigt Wednesday, September 3, 2014 4:18 PM typo
    Wednesday, September 3, 2014 4:15 PM

Answers

  • Hi there!

    You are on the wrong avenue. You need to declare the getContent attribute instead and specify the callback where an XML string is returned (contains the contents of this dynamic menu).

    Thanks, I think this got me on the right track!

    So any static/monolithic/bulk ribbon content (programmatically created nested IRibbonControl collections or nested RibbonX elements in a string) is limited to 5 levels at any time. To go deeper one will have to use a callback every other level (or at least every 4th level).

    This approach seemst to work with really deep nesting levels:

    public string GetContent(IRibbonControl control) {
      return @"
        <menu xmlns=""http://schemas.microsoft.com/office/2006/01/customui"" >
          <button id=""button1"" label=""Level 1"" onAction=""OnAction""  imageMso=""HappyFace"" />
          <menu id=""menu1"">
            <button id=""button2"" label=""Level 2"" onAction=""OnAction""  imageMso=""HappyFace"" />
            <menu id=""menu2"">
              <button id=""button3"" label=""Level 3"" onAction=""OnAction""  imageMso=""HappyFace"" />
              <menu id=""menu3"">
                <button id=""button4"" label=""Level 4"" onAction=""OnAction""  imageMso=""HappyFace"" />
                <dynamicMenu id=""dynamicMenu2""
                    label=""Dynamic Menu""
                    getContent=""GetContent"" 
                />
              </menu>
            </menu>
          </menu>
        </menu>
      ";
    }
    Looks like I'll have to update my menu tree building algorithm (used to build my complete IRibbonControl collection from the leaves to the root in one go and assign it using a single RibbonControlEventHandler)...

    Still wish this limitation was documented somewhere.

    Thanks again for your kind efforts,
    Thomas

    • Marked as answer by tvoigt Thursday, September 11, 2014 4:36 PM
    Thursday, September 11, 2014 4:35 PM

All replies

  • Hello Thomas,

    I'd suggest using the dynamicMenu instead. Represents a menu that is created at run time. I hope you will be able to override the limit of 5 levels. You can read more about ribbon controls in the following articles in MSDN:

    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)Also you may find helpful the following pages:

    Customizing Context Menus in Office 2010

    Introduction to the Office 2010 Backstage View for Developers

    • Marked as answer by George HuaModerator Thursday, September 11, 2014 9:06 AM
    • Unmarked as answer by tvoigt Thursday, September 11, 2014 11:05 AM
    Wednesday, September 3, 2014 4:53 PM
  • Hi there!

    Thanks for getting back to me so quickly.

    My understanding is that instanciating "RibbonMenu" items (using C#) is equivalent to filling some <dynamicMenu> declaratively (using XML).

    Simple test case: Creating a dynamic menu...

    public string GetContent(IRibbonControl control) {
    	return @"
    		<menu xmlns=""http://schemas.microsoft.com/office/2006/01/customui"" >
    			<button id=""button1"" label=""Level 1"" onAction=""OnAction""  imageMso=""HappyFace"" />
    			<menu id=""menu1"">
    				<button id=""button2"" label=""Level 2"" onAction=""OnAction""  imageMso=""HappyFace"" />
    				<menu id=""menu2"">
    					<button id=""button3"" label=""Level 3"" onAction=""OnAction""  imageMso=""HappyFace"" />
    					<menu id=""menu3"">
    						<button id=""button4"" label=""Level 4"" onAction=""OnAction""  imageMso=""HappyFace"" />
    						<menu id=""menu4"">
    							<button id=""button5"" label=""Level 5"" onAction=""OnAction""  imageMso=""HappyFace"" />
    							<menu id=""menu5"">
    								<button id=""button6"" label=""Level 6"" onAction=""OnAction""  imageMso=""HappyFace"" />
    								<menu id=""menu6"">
    									<button id=""button7"" label=""Level 7"" onAction=""OnAction""  imageMso=""HappyFace"" />
    								</menu>
    							</menu>
    						</menu>
    					</menu>
    				</menu>
    			</menu>
    		</menu>
    	";
    }
    ...yields the same result:

    dynamicMenu with only 5 levels

    A menu that is limited to only five levels.

    So my questions remain unanswered:

    • Why is there a nest limit?
    • Where is it documented?
    • How can I override it?

    Thanks and best regards,
    Thomas

    Thursday, September 11, 2014 11:29 AM
  • Hello,

    > My understanding is that instanciating "RibbonMenu" items (using C#) is equivalent to filling some <dynamicMenu> declaratively (using XML).

    You are on the wrong avenue. You need to declare the getContent attribute instead and specify the callback where an XML string is returned (contains the contents of this dynamic menu).

    Again, you can read more about the Ribbon UI in the following series of articles in MSDN:

    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)

    <dynamicMenu id="subMenu" label="Sub Menu" getContent="GetSubContent" />
    
    

    Thursday, September 11, 2014 2:50 PM
  • Hi there!

    You are on the wrong avenue. You need to declare the getContent attribute instead and specify the callback where an XML string is returned (contains the contents of this dynamic menu).

    Thanks, I think this got me on the right track!

    So any static/monolithic/bulk ribbon content (programmatically created nested IRibbonControl collections or nested RibbonX elements in a string) is limited to 5 levels at any time. To go deeper one will have to use a callback every other level (or at least every 4th level).

    This approach seemst to work with really deep nesting levels:

    public string GetContent(IRibbonControl control) {
      return @"
        <menu xmlns=""http://schemas.microsoft.com/office/2006/01/customui"" >
          <button id=""button1"" label=""Level 1"" onAction=""OnAction""  imageMso=""HappyFace"" />
          <menu id=""menu1"">
            <button id=""button2"" label=""Level 2"" onAction=""OnAction""  imageMso=""HappyFace"" />
            <menu id=""menu2"">
              <button id=""button3"" label=""Level 3"" onAction=""OnAction""  imageMso=""HappyFace"" />
              <menu id=""menu3"">
                <button id=""button4"" label=""Level 4"" onAction=""OnAction""  imageMso=""HappyFace"" />
                <dynamicMenu id=""dynamicMenu2""
                    label=""Dynamic Menu""
                    getContent=""GetContent"" 
                />
              </menu>
            </menu>
          </menu>
        </menu>
      ";
    }
    Looks like I'll have to update my menu tree building algorithm (used to build my complete IRibbonControl collection from the leaves to the root in one go and assign it using a single RibbonControlEventHandler)...

    Still wish this limitation was documented somewhere.

    Thanks again for your kind efforts,
    Thomas

    • Marked as answer by tvoigt Thursday, September 11, 2014 4:36 PM
    Thursday, September 11, 2014 4:35 PM