SharePoint Ribbon. Creating multi level menu

SharePoint 2010/2013 Ribbon API (In Russian)
SharePoint Ribbon. Using ColorPicker (In Russian)
SharePoint Ribbon. Creating multi level menu

Another use case of QASPRibbon: creating multi-level menu in Ribbon.

In SharePoint dropdown menu is available in following elements:

  • FlyoutAnchor
  • SplitButton
  • MRUSplitButon
  • DropDown
  • ComboBox.

Each menu contains sections (MenuSection) which can contain buttons (Button) or flyout anchors (FlyoutAnchor) for showing sub-level menu.

Declaration of drop down menu (DropDown) which contains menu and sub menu is like the following (without attributes):

<DropDown>
  <Menu>
    <Controls>
      <MenuSection>
        <Controls>
          <Button><!-- Button - menu item --></Button>
          <FlyoutAnchor> <!-- Fly out anchor -->
            <Menu>
              <Controls>
                <MenuSection>
                  <Controls>
                    <Button><!-- Button - menu item --><Button>
                  </Controls>
                </MenuSection>
              </Controls>
            </Menu>
          </FlyoutAnchor>
        </Controls>
      </MenuSection>
    </Controls>
  </Menu>
</DropDown>

The result is a two-tired menu. First of them contains a button and anchor to the second tire containing a button.

To achieve the same result using QASPRibbon just use the followin code:

var dropDown = new RibbonDropDown("DropDownId", "DropDownTitle")
{
    Sections = new[]
    {
        new RibbonMenuSection("SectionId", "SectionTitle")
        {
            Controls = new RibbonControl[]
            {
                new RibbonButton("ButtonId", "ButtonTitle"),
                new RibbonFlyoutAnchor("FlyoutAnchorId", "FlyoutAnchorTitle")
                {
                    Sections = new[]
                    {
                        new RibbonMenuSection("SectionId", "SectionTitle")
                        {
                            Controls = new RibbonControl[]
                            {
                                new RibbonButton("ButtonId", "ButtonTitle")
                            }
                        }
                    }
                }
            }
        }
    }
};

At first sight, this code is not good. But there are these undeniable advantages:

  • Creating a menu dynamically based on any data (SharePoint list) is very simple. Using .Select(x=> new RibbonButton(x.Id.ToString(), x.Title){...}) method is almost always enough. You can write 2-3 methods that generate XML-declaration, but the convenience of this approach will be poor. Encapsulation is very easy to develop and support solutions;
  • Using a handler on the server-side. Again, encapsulation, to avoid problems;
  • Modification of ribbon-element. In the case of using native SharePoint API, you have to parse XML (testing of this solution will cost dearly). In case of using QASRibbon classes your solution becomes very simple;

For convenience, create a simple method that returns the menu section, the above:

private RibbonMenuSection[] GetFakeMenuSections()
{
    return new[]
    {
        new RibbonMenuSection("SectionId", "SectionTitle")
        {
            //Image 32x32 + text
            DisplayMode = RibbonMenuDisplayMode.Menu32,
            Controls = new RibbonControl[]
            {
                new RibbonButton("ButtonId", "ButtonTitle")
                {
                    Image = RibbonImageDefinition.Standard(7, 7)
                },
                new RibbonFlyoutAnchor("FlyoutAnchorId", "FlyoutAnchorTitle")
                {
                    Image = RibbonImageDefinition.Standard(7, 7),
                    Sections = new[]
                    {
                        new RibbonMenuSection("SectionId", "SectionTitle")
                        {
                            Controls = new RibbonControl[]
                            {
                                new RibbonButton("ButtonId", "ButtonTitle")
                                {
                                    Image = RibbonImageDefinition.Standard(7, 7)
                                }
                            }
                        }
                    }
                }
            }
        }
    };
}

This will reduce the amount of code in the future.

We now proceed directly to the creation of the menu. That's code for a simple tab, affiliated group and child drop-down menu:

// A new tab
var menuTab = new RibbonTab("MenuTab", "Menu demo tab")
{
    // Sequential number is not multiple of 100
    Sequence = 550,
    // Setting a sequential number of element
    Groups = new[]
    {
        // A new group of elements
        new RibbonGroup("MenuGroup", "Menu demo group")
        {
            // Setting &vertical alignment to middle
            Alignment = RibbonGroupAlignment.Middle,
            // Show image and label
            DisplayMode = RibbonDisplayMode.Image16AndCaption,
            // Elements in two rows
            Template = RibbonGroupTemplate.TwoRows,
            Controls = new RibbonControl[]
            {
                new RibbonDropDown("DropDownId", "DropDownTitle")
                {
                    Sections = GetFakeMenuSections()
                },
                new RibbonComboBox("ComboBoxId", "ComboBoxTitle")
                {
                    Sections = GetFakeMenuSections()
                },
                new RibbonFlyoutAnchor("FlyoutAnchorId", "FlyoutAnchorTitle")
                {
                    Image = RibbonImageDefinition.Standard(7, 8),
                    Sections = GetFakeMenuSections()
                },
                new RibbonSplitButton("SplitButtonId", "SplitButtonTitle")
                {
                    Image = RibbonImageDefinition.Standard(7, 8),
                    Sections = GetFakeMenuSections()
                }
            }
        }
    }
};

A very simple code. SplitButton, the above, has an image, 'cause it is not only a menu container but also a button. You can use MRUSplitButton element like SlitButton, but it requires a one-row layout of the parent group.

I used a tow-rows layout for the group (TwoRows). What other layouts are and how they look you can see in the project documentation. The sequential number of groups is not multiple of 100, these numbers are used by standard SharePoint tabs.

And now adding tab to the ribbon:

RibbonManager.Current.AddTabToPage(menuTab, Page);

And the result of it in browser:

SharePoint Ribbon DropDown

SharePoint Ribbon ComboBox

SharePoint Ribbon FlyoutAnchor

SharePoint Ribbon SplitButton

When a menu item in the ComboBox or DropDown controls are selected their corresponding container filled with text from the selected item and users will be able to see what they chose:

SharePoint Ribbon ComboBox

When using the standard tools for SharePoint Ribbon, would have to use here such XML-code:

<?xml version="1.0" encoding="utf-8"?>
<Tab Id="Ribbon.MenuTab" Title="Menu demo tab" CssClass="" Sequence="550">
 <Scaling Id="Ribbon.MenuTab.Scaling">
  <MaxSize Id="Ribbon.MenuTab.MenuGroup.MaxSize" GroupId="Ribbon.MenuTab.MenuGroup" Size="Ribbon.MenuTab.MenuGroupLayout" Sequence="10" />
 </Scaling>
 <Groups Id="Ribbon.MenuTab.Groups">
  <Group Id="Ribbon.MenuTab.MenuGroup" Title="Menu demo group" Description="" Sequence="1" Template="Ribbon.MenuTab.MenuGroupTemplate">
   <Controls Id="Ribbon.MenuTab.MenuGroup.Controls">
    <DropDown Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId" Sequence="1" Width="100px" TemplateAlias="Ribbon.MenuTab.MenuGroupLayout1MediumRowI" CacheMenuVersions="true" PopulateDynamically="false" PopulateOnlyOnce="false" QueryCommand="Ribbon.MenuTab.MenuGroup.Controls.DropDownIdQueryCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.DropDownIdCommand" CommandMenuOpen="Ribbon.MenuTab.MenuGroup.Controls.DropDownIdCommandMenuOpen" CommandMenuClose="Ribbon.MenuTab.MenuGroup.Controls.DropDownIdCommandMenuClose">
     <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu">
      <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu16" Scrollable="true">
       <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls">
        <Button Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.ButtonIdCommand" />
        <FlyoutAnchor Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId" Sequence="2" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="FlyoutAnchorTitle" TemplateAlias="" PopulateQueryCommand="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorIdPopulateQueryCommand" CommandMenuClose="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorIdCommandMenuClose" Command="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorIdCommand" CommandQuery="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorIdCommandQuery" CacheMenuVersions="true" PopulateDynamically="false" PopulateOnlyOnce="false">
         <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId.Menu">
          <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu32" Scrollable="true">
           <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls">
            <Button Id="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.DropDownId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" />
           </Controls>
          </MenuSection>
         </Menu>
        </FlyoutAnchor>
       </Controls>
      </MenuSection>
     </Menu>
    </DropDown>
    <ComboBox Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId" Sequence="2" Width="100px" AutoComplete="true" AutoCompleteDelay="100" AllowFreeForm="false" TemplateAlias="Ribbon.MenuTab.MenuGroupLayout1MediumRowII" CacheMenuVersions="false" PopulateDynamically="false" PopulateOnlyOnce="false" QueryCommand="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxIdQueryCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxIdCommand" CommandMenuOpen="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxIdCommandMenuOpen" CommandMenuClose="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxIdCommandMenuClose" InitialItem="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.ButtonId">
     <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu">
      <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu16" Scrollable="true">
       <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls">
        <Button Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.ButtonIdCommand" />
        <FlyoutAnchor Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId" Sequence="2" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="FlyoutAnchorTitle" TemplateAlias="" PopulateQueryCommand="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorIdPopulateQueryCommand" CommandMenuClose="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorIdCommandMenuClose" Command="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorIdCommand" CommandQuery="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorIdCommandQuery" CacheMenuVersions="true" PopulateDynamically="false" PopulateOnlyOnce="false">
         <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId.Menu">
          <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu32" Scrollable="true">
           <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls">
            <Button Id="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.ComboBoxId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" />
           </Controls>
          </MenuSection>
         </Menu>
        </FlyoutAnchor>
       </Controls>
      </MenuSection>
     </Menu>
    </ComboBox>
    <FlyoutAnchor Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId" Sequence="3" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-128" Image32by32Top="-256" LabelText="FlyoutAnchorTitle" TemplateAlias="Ribbon.MenuTab.MenuGroupLayout2MediumRowI" PopulateQueryCommand="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorIdPopulateQueryCommand" CommandMenuClose="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorIdCommandMenuClose" Command="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorIdCommand" CommandQuery="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorIdCommandQuery" CacheMenuVersions="true" PopulateDynamically="false" PopulateOnlyOnce="false">
     <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu">
      <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu16" Scrollable="true">
       <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls">
        <Button Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" />
        <FlyoutAnchor Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId" Sequence="2" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="FlyoutAnchorTitle" TemplateAlias="" PopulateQueryCommand="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorIdPopulateQueryCommand" CommandMenuClose="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorIdCommandMenuClose" Command="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorIdCommand" CommandQuery="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorIdCommandQuery" CacheMenuVersions="true" PopulateDynamically="false" PopulateOnlyOnce="false">
         <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId.Menu">
          <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu32" Scrollable="true">
           <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls">
            <Button Id="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.FlyoutAnchorId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" />
           </Controls>
          </MenuSection>
         </Menu>
        </FlyoutAnchor>
       </Controls>
      </MenuSection>
     </Menu>
    </FlyoutAnchor>
    <SplitButton Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId" Sequence="4" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-128" Image32by32Top="-256" LabelText="SplitButtonTitle" TemplateAlias="Ribbon.MenuTab.MenuGroupLayout2MediumRowII" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonIdCommand" CommandQuery="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonIdCommandQuery">
     <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu">
      <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu16" Scrollable="true">
       <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls">
        <Button Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.ButtonIdCommand" />
        <FlyoutAnchor Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId" Sequence="2" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="FlyoutAnchorTitle" TemplateAlias="" PopulateQueryCommand="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorIdPopulateQueryCommand" CommandMenuClose="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorIdCommandMenuClose" Command="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorIdCommand" CommandQuery="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorIdCommandQuery" CacheMenuVersions="true" PopulateDynamically="false" PopulateOnlyOnce="false">
         <Menu Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId.Menu">
          <MenuSection Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId" Sequence="1" Title="SectionTitle" DisplayMode="Menu32" Scrollable="true">
           <Controls Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls">
            <Button Id="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" Sequence="1" Image16by16="/_layouts/1033/images/formatmap16x16.png" Image32by32="/_layouts/1033/images/formatmap32x32.png" Image16by16Left="-112" Image32by32Left="-224" Image16by16Top="-112" Image32by32Top="-224" LabelText="ButtonTitle" MenuItemId="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonId" CommandValueId="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" Command="Ribbon.MenuTab.MenuGroup.Controls.SplitButtonId.Menu.SectionId.Controls.FlyoutAnchorId.Menu.SectionId.Controls.ButtonIdCommand" />
           </Controls>
          </MenuSection>
         </Menu>
        </FlyoutAnchor>
       </Controls>
      </MenuSection>
     </Menu>
    </SplitButton>
   </Controls>
  </Group>
 </Groups>
</Tab>

Finally about ComboBox. It supports auto-completion, but it works only for the first menu tire. All other menu items (on the second tire and below) in the results do not appear. This does not stop them from manually choose.

Vitaly Zhukov

Vitaly Zhukov

SharePoint Architect, Developer, Technical Trainer, Microsoft MVP (Office Development). Above 15 years of total experience working with SharePoint, Dynamics CRM, Office 365, and Microsoft stack development.

You May Also Like

Collect SharePoint telemetry with Azure Application Insights. Part I. Server-Side

Collect SharePoint telemetry with Azure Application Insights. Part I. Server-Side

SharePoint New Team Site. Inside Out

SharePoint New Team Site. Inside Out

SharePoint 2019 Preview

SharePoint 2019 Preview

SharePoint 2013. Geolocation field type

SharePoint 2013. Geolocation field type

Mask "Created By" and "Modified By" user names from forms and views

Mask "Created By" and "Modified By" user names from forms and views

SharePoint list item attachments' size

SharePoint list item attachments' size

SharePoint 2010. Custom forms for ContentType

SharePoint 2010. Custom forms for ContentType

SharePoint 2007. The max/min value of filed in SharePoint list

SharePoint 2007. The max/min value of filed in SharePoint list