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.
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.
Merge Names
The merging mechanism uses the following item’s properties to match items from the parent and child bars:
- MergingProperties.Name
- x:Name that is mapped to a BarItemLink‘s BarItemName property.
- 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).
<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>
- 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).
<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>
- Remove
The bar item links of a child BarManager’s bar/link container with identical captions are removed from the parent bar.
<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>
- Replace
The bar item links of a child BarManager’s bar/link container replace item links on the parent bar with identical captions.
<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>
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.
You can merge the following elements:
- RibbonPageCategory items
- RibbonPages
- RibbonPageGroups
- BarItems within page groups, quick access toolbars, and ribbon status bar controls. These elements are added from a child RibbonControl/RibbonStatusBarControl to the parent RibbonControl/RibbonStatusBarControl.
Merge Names
The Merging mechanism uses the following item’s properties to match items from the parent and child ribbons:
- MergingProperties.Name
- x:Name that is mapped to a BarItemLink‘s BarItemName property.
- 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:
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:
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:
- In regular MDI mode, when a DocumentPanel is maximized.
- In tabbed MDI mode, when a tab (DocumentPanel) is activated.
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>