Skip to main content

Merge Bars and Ribbons in MDI Mode

  • 10 minutes to read

You can implement Multiple-Document Interface (MDI) mode in your applications that use the DocumentGroup and DocumentPanel objects.

The DocumentGroup and each of its child DocumentPanels can have its own menus, bars and ribbons. To avoid duplicating these toolbars/ribbons, you can merge them from child into parent windows.

Run Demo: MDI Ribbon Merging Demo

Merge Bars

As an example, the DocumentGroup‘s menu can have general commands that work with files, windows, and its child panels can have bars and menus that perform panel-specific actions. In this case, you can merge a child panel’s menus and bars into the parent’s menus and bars when the panel is expanded.

Mdi_Merging

View Example: Merge Bars in MDI Mode

Merge Names

The merging mechanism uses the following item’s properties to match items from the parent and child bars:

  1. MergingProperties.Name
  2. x:Name that is mapped to a BarItemLink‘s BarItemName property.
  3. BarItem.Content

Merge Type

Use the BarItemLinkBase.MergeType property to select a merge type. You should specify this property only for a child BarManager’s items and links that you want to merge. You can choose one of the following merge types:

Add

The bar item links of a child BarManager’s bar/link container are added to the parent BarManager’s bar/link container (the default behavior).

Show Code
<Grid>
    <DockPanel>
        <!-- Parent Bar Items -->
        <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
            <dxb:MainMenuControl.Items>
                <dxb:BarButtonItem
                    Content="Open"
                    ItemClick="parent_bar_open"
                    MergeOrder="0" />
                <dxb:BarButtonItem
                    Content="Save"
                    ItemClick="parent_bar_save"
                    MergeOrder="1" />
                <dxb:BarButtonItem
                    Content="MDI"
                    ItemClick="biMDI_ItemClick"
                    MergeOrder="3" />
                <dxb:BarButtonItem
                    Content="Tabbed"
                    ItemClick="biTabbed_ItemClick"
                    MergeOrder="4" />
            </dxb:MainMenuControl.Items>
        </dxb:MainMenuControl>
        <Grid>
            <dxdo:DockLayoutManager x:Name="dlManager">
                <dxdo:LayoutGroup>
                    <dxdo:DocumentGroup>
                        <dxdo:DocumentPanel>
                            <Grid>
                                <DockPanel>
                                    <!-- Child Bar Items -->
                                    <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
                                        <dxb:BarButtonItem Content="Open" 
                                        MergeOrder="0" MergeType="Add" />
                                        <dxb:BarButtonItem Content="Save"
                                        MergeOrder="1" MergeType="Add" />
                                        <dxb:BarButtonItem Content="Close" MergeOrder="2" />
                                    </dxb:MainMenuControl>
                                       <!-- ... -->
                                </DockPanel>
                            </Grid>
                        </dxdo:DocumentPanel>
                    </dxdo:DocumentGroup>
                </dxdo:LayoutGroup>
            </dxdo:DockLayoutManager>
        </Grid>
    </DockPanel>
</Grid>

DockLayoutManager Merging - MergeType.Remove

MergeItems

This setting is applied to link the following containers: Bar, BarSubItem, PopupMenu, BarLinkContainerItem.

When this setting is applied, the child container’s links are merged into the parent container with the same caption. If the captions of these containers are different, the child container’s links are added to the parent container (similar to the Add setting).

Show Code
<Grid>
    <DockPanel>
        <!-- Parent Bar Items -->
        <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
            <dxb:MainMenuControl.Items>
                <dxb:BarSubItem Content="File">
                    <dxb:BarSubItem.Items>
                        <dxb:BarButtonItem
                            Content="Open"
                            ItemClick="parent_bar_open"
                            MergeOrder="0" />
                        <dxb:BarButtonItem
                            Content="Save"
                            ItemClick="parent_bar_save"
                            MergeOrder="1" />
                        <dxb:BarButtonItem Content="MDI" MergeOrder="3" />
                        <dxb:BarButtonItem Content="Tabbed" MergeOrder="4" />
                    </dxb:BarSubItem.Items>
                </dxb:BarSubItem>
            </dxb:MainMenuControl.Items>
        </dxb:MainMenuControl>
        <Grid>
            <dxdo:DockLayoutManager x:Name="dlManager">
                <dxdo:LayoutGroup>
                    <dxdo:DocumentGroup>
                        <dxdo:DocumentPanel>
                            <Grid>
                                <DockPanel>
                                    <!-- Child Bar Items -->
                                    <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
                                        <dxb:MainMenuControl.Items>
                                            <dxb:BarSubItem Content="File" MergeType="MergeItems">
                                                <dxb:BarButtonItem
                                                    Content="Open"
                                                    ItemClick="child_bar_open"
                                                    MergeOrder="0"
                                                    MergeType="Replace" />
                                                <dxb:BarButtonItem
                                                    Content="Save"
                                                    ItemClick="child_bar_save"
                                                    MergeOrder="1"
                                                    MergeType="Replace" />
                                                <dxb:BarButtonItem Content="Close" MergeOrder="2" />
                                            </dxb:BarSubItem>
                                        </dxb:MainMenuControl.Items>
                                    </dxb:MainMenuControl>
                                       <!-- ... -->
                                </DockPanel>
                            </Grid>
                        </dxdo:DocumentPanel>
                    </dxdo:DocumentGroup>
                </dxdo:LayoutGroup>
            </dxdo:DockLayoutManager>
        </Grid>
    </DockPanel>
</Grid>

DockLayoutManager Merging - MergeType.Remove

Remove

The bar item links of a child BarManager’s bar/link container with identical captions are removed from the parent bar.

Show Code
<Grid>
    <DockPanel>
        <!-- Parent Bar Items -->
        <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
            <dxb:MainMenuControl.Items>
                <dxb:BarButtonItem Content="Open" MergeOrder="0" ItemsClick="parent_bar_open" />
                <dxb:BarButtonItem Content="Save" MergeOrder="1" ItemsClick="parent_bar_save" />
                <dxb:BarButtonItem Content="MDI" MergeOrder="3" />
                <dxb:BarButtonItem Content="Tabbed" MergeOrder="4" />
            </dxb:MainMenuControl.Items>
        </dxb:MainMenuControl>
        <Grid>
            <dxdo:DockLayoutManager x:Name="dlManager">
                <dxdo:LayoutGroup>
                    <dxdo:DocumentGroup>
                        <dxdo:DocumentPanel>
                            <Grid>
                                <DockPanel>
                                    <!-- Child Bar Items -->
                                    <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
                                        <dxb:BarButtonItem Content="Open" 
                                        ItemsClick="child_bar_open" MergeOrder="0" MergeType="Remove" />
                                        <dxb:BarButtonItem Content="Save"
                                        ItemsClick="child_bar_save" MergeOrder="1" MergeType="Remove" />
                                        <dxb:BarButtonItem Content="Close" MergeOrder="2" />
                                    </dxb:MainMenuControl>
                                       <!-- ... -->
                                </DockPanel>
                            </Grid>
                        </dxdo:DocumentPanel>
                    </dxdo:DocumentGroup>
                </dxdo:LayoutGroup>
            </dxdo:DockLayoutManager>
        </Grid>
    </DockPanel>
</Grid>

DockLayoutManager Merging - MergeType.Remove

Replace

The bar item links of a child BarManager’s bar/link container replace item links on the parent bar with identical captions.

Show Code
<Grid>
    <DockPanel>
        <!-- Parent Bar Items -->
        <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
            <dxb:MainMenuControl.Items>
                <dxb:BarButtonItem Content="Open" MergeOrder="0" ItemClick="parent_bar_open" />
                <dxb:BarButtonItem Content="Save" MergeOrder="1" ItemClick="parent_bar_save" />
                <dxb:BarButtonItem Content="MDI" MergeOrder="3" />
                <dxb:BarButtonItem Content="Tabbed" MergeOrder="4" />
            </dxb:MainMenuControl.Items>
        </dxb:MainMenuControl>
        <Grid>
            <dxdo:DockLayoutManager x:Name="dlManager">
                <dxdo:LayoutGroup>
                    <dxdo:DocumentGroup>
                        <dxdo:DocumentPanel>
                            <Grid>
                                <DockPanel>
                                    <!-- Child Bar Items -->
                                    <dxb:MainMenuControl Caption="File" DockPanel.Dock="Top">
                                        <dxb:BarButtonItem Content="Open" 
                                        ItemsClick="child_bar_open"  MergeOrder="0" MergeType="Replace" />
                                        <dxb:BarButtonItem Content="Save"
                                        ItemsClick="child_bar_save"  MergeOrder="1" MergeType="Replace" />
                                        <dxb:BarButtonItem Content="Close" MergeOrder="2" />
                                    </dxb:MainMenuControl>
                                       <!-- ... -->
                                </DockPanel>
                            </Grid>
                        </dxdo:DocumentPanel>
                    </dxdo:DocumentGroup>
                </dxdo:LayoutGroup>
            </dxdo:DockLayoutManager>
        </Grid>
    </DockPanel>
</Grid>

DockLayoutManager Merging - MergeType.Remove

Merge Order

Each merged bar/menu link has the MergeOrder property that specifies the order in which parent and child bar elements are displayed in the merged bar.

Links with the lowest MergeOrder are displayed first. The last few links are those that have the greatest MergeOrder value.

If a parent and child BarManager’s links have equal MergeOrder values, the parent BarManager’s links are placed first, and then the child BarManager’s links are placed.

Merge a Panel’s Bars with ThemedWindow ToolbarItems/HeaderItems

A panel’s bar items can be embedded into the a ThemedWindow‘s ToolbarItems / HeaderItems bar collections. If a ThemedWindow‘s bar is defined in ToolbarItems or HeaderItems, the panel merges its control box buttons with this bar. If a ThemedWindow contains a bar both in ToolbarItems and HeaderItems, the panel merges its control box buttons with HeaderItems.

Merge/Unmerge Bar Manually

Handle the following events to merge or unmerge a bar/menu:

Event Description
DockLayoutManager.Merge Allows you to customize menus and bars when the merging mechanism is invoked.
DockLayoutManager.UnMerge Allows you to undo bars customizations performed via the DockLayoutManager.Merge event. This event also allows you to undo the results of the manual merge operation that you performed with the DockLayoutManager.Merge event handler.

When you populate a bar with items from a ViewModel collection, you should populate a bar and then merge another bar with it. To do this, disable the automatic merging and manually merge bars when they are loaded.

Merge/Restore Two Bars that Belong to Different BarManagers

Call the parent bar’s Merge method to merge two bars that belong to different BarManagers.

After bars are merged, you can call any of the Bar.UnMerge methods to restore the original bars/menus layout.

Merge Sub Menus and Their Items

Call the ILinksHolder.Merge and ILinksHolder.UnMerge methods to merge/unmerge menus of containers that implement the ILinksHolder interface.

Disable a Panel’s Toolbar Merging

Set the panel’s ElementMergingBehavior attached property to None to disable toolbar merging for the panel:

<Window ...
    xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking">
    <dxdo:DockLayoutManager>
        <dxdo:LayoutGroup>
            <dxdo:DocumentGroup>
                <dxdo:DocumentPanel Caption="Document1" dxb:MergingProperties.ElementMergingBehavior="None">
                    <!-- ... -->
                </dxdo:DocumentPanel>
                <dxdo:DocumentPanel Caption="Document2"/>
            </dxdo:DocumentGroup>
            </dxdo:LayoutGroup>
    </dxdo:DockLayoutManager>
</Window>  

Customize Merging

Toolbar Merge

You can use the following properties to customize a toolbar merge:

ElementMergingBehavior
Gets or sets whether the current container’s elements are merged with elements of outside containers or elements of the same container or both. Also allows you to disable merging. This is an attached property.
ToolBarMergeStyle
Gets or sets the type of controls for which automatic merging is enabled. This is an attached property.
Name
Gets or sets a “merge name”. This is an attached property.

Merge Ribbons

As with the bars and menus, you can merge a child panel with a parent group’s RibbonControls.

DXRibbon merging GIF

You can merge the following elements:

View Example: Merge Ribbon Controls in MDI Mode

Merge Names

The Merging mechanism uses the following item’s properties to match items from the parent and child ribbons:

  1. MergingProperties.Name
  2. x:Name that is mapped to a BarItemLink‘s BarItemName property.
  3. BarItem.Content

Merge Type

Use the MergeType property to select a merge type. You should specify this property only for a child ribbon’s items and links that you want to merge. You can choose one of the following merge types:

Ribbon Element Property
RibbonPageCategory RibbonPageCategoryBase.MergeType
RibbonPage RibbonPage.MergeType
RibbonPageGroup RibbonPageGroup.MergeType
BarItemLinkBase BarItemLinkBase.MergeType

You can choose one of the following merge types:

Value Description
Add The ribbon items of a child ribbon are added to the parent ribbon (the default behavior).
MergeItems The default merging mechanism. Sub-items of the current child ribbon element are merged into the parent ribbon element that has the same caption. If no parent element with the same caption exists, the current child ribbon element is appended according to its MergeOrder.
Remove The ribbon items of a child ribbon with identical captions are removed from a merged ribbon.
Replace The ribbon items of a child ribbon replace ribbon items on the parent ribbon with identical captions.

Merge Order

Each merged element has the MergeOrder property that specifies the order in which parent/child ribbon’s items are displayed in the merged ribbon.

The first element’s MergeOrder is 0. An element with the greatest MergeOrder value is the last. The default MergeOrder value for all elements is 0.

If parent and child ribbons include items with equal MergeOrder property values, the child ribbon’s items are placed after all parent ribbon’s items with that MergeOrder.

You can use the following properties to specify the merge order of different elements of a ribbon:

Property Description
RibbonPageCategory RibbonPageCategoryBase.MergeOrder
RibbonPage RibbonPage.MergeOrder
RibbonPageGroup RibbonPageGroup.MergeOrder
BarItemLinkBase BarItemLinkBase.MergeOrder

The Ribbon control merges and arranges its elements in the following order:

  1. RibbonPageCategories
  2. RibbonPages
  3. RibbonPageGroups
  4. Ribbon’s items and commands

Example

<!-- The parent Ribbon Control: -->
<dxr:RibbonPage MergeOrder="0" Caption="Home" Name="mainHomePage">
    <!-- ... -->
</dxr:RibbonPage>
<dxr:RibbonPage MergeOrder="2" Caption="View" Name="mainViewPage">
    <!-- ...  -->
</dxr:RibbonPage>

<!-- The child Ribbon Control: -->
<dxr:RibbonPage MergeOrder="1" Caption="Insert" Name="child2InsertPage">
    <!-- ... -->
</dxr:RibbonPage>
<dxr:RibbonPage MergeOrder="4" Caption="Add-ins" Name="child2AddInsPage">
    <!-- ... -->
</dxr:RibbonPage>
<dxr:RibbonPage MergeOrder="3" Caption="Test" Name="child2TestPage">
    <!-- ... -->
</dxr:RibbonPage>

The following image demonstrates a merge result:

DXRibbon merge order example image

Unmerge Ribbons

Call the RibbonControl.UnMerge / RibbonStatusBarControl.UnMerge methods to unmerge RibbonControl / RibbonStatusBarControl.

If you merged multiple Ribbon objects, you can define which child Ribbon object should be unmerged from the parent object.

To restore the parent control’s layout, call an Unmerge method without parameters.

Change the Default Merge Behavior

Menus, bars, and ribbons are merged in the following cases:

Menus, bars, and ribbons are unmerged in the following cases:

  • In regular MDI mode, when a DocumentPanel is restored from the maximized to the normal state or before another DocumentPanel is maximized.
  • In tabbed MDI mode, when a tab (DocumentPanel) is deactivated (for instance, before another tab is selected).

You can use the DockLayoutManager.MDIMergeStyle property to change the default bar merging behavior. This property affects all child panels within a DockLayoutManager. You can choose one of the following values:

Always

The panel’s bar/ribbon is merged with the parent bar/ribbon in the following cases:

  • When you maximize a DocumentGroup‘s MDI child panel (MDI UI).
  • When you select the DocumentGroup‘s panel in the tab (tabbed UI).

If your layout contains multiple DocumentGroups, the merging mechanism is invoked for all DocumentGroups simultaneously. In this case, all of them are merged to the parent at the same time.

Bars/ribbons are unmerged in the following cases:

  • When you restore an MDI child panel from the maximized state to the normal state (MDI UI).
  • When you select another tab (Tabbed UI).
Never
Prevents all child tabbed and MDI panels from being merged.
WhenChildActivated

Bars/ribbons are merged in the following cases:

  • When you activate a maximized MDI child panel (MDI UI).
  • When you select a tab (tabbed UI).

Bars/ribbons are unmerged in the following cases:

  • When you restore a maximized MDI child panel from the maximized to the normal state or deactivate it (MDI UI).
  • When you deactivate a selected tab or select another tab (tabbed UI).
WhenLoadedOrChildActivated
Similar to WhenChildActivated mode, but additionally merges MDI panels and tabs that are initially maximized (docked), but not yet selected (for example, on application start).

Change a Panel’s Merge Behavior

Use the DocumentPanel.MDIMergeStyle attached property to specify the merge behavior for the panel. This property has a higher priority than the DockLayoutManager.MDIMergeStyle property.

Layout Panel Specifics

Bars and Ribbons included in LayoutPanels are not merged with the parent container (the default behavior).

Set the LayoutPanel bar/ribbon’s ElementMergingBehavior property to InternalWithExternal to merge a LayoutPanel‘s bars/ribbons with a parent container:

<Style TargetType="dxdo:LayoutPanel">  
    <Setter Property="dxb:MergingProperties.ElementMergingBehavior" Value="InternalWithExternal" />  
</Style>  
See Also