MDI Merging
- 7 minutes to read
MDI Bar Merging combines links from parent and child window toolbars in MDI applications.
By default, only main menus merge automatically. Regular and status bars must be merged manually.
Also, note that the Bar Manager does not merge items whose Visibility is disabled. Set the BarManager.AllowMergeInvisibleLinks property to true to change this behavior.
Merge Main Menus
Create a sample MDI application based on standard or DevExpress forms.
//Main MDI Form public partial class Form1 : DevExpress.XtraEditors.XtraForm { public Form1() { InitializeComponent(); //this form is a parent MDI window this.IsMdiContainer = true; } private void Form1_Load(object sender, EventArgs e) { //create and show child MDI windows MdiForm1 tab1 = new MdiForm1(this) { Text = "Child Window 1" }; MdiForm2 tab2 = new MdiForm2(this) { Text = "Child Window 2" }; tab1.Show(); tab2.Show(); } } //Child MDI Forms public partial class MdiForm1: DevExpress.XtraEditors.XtraForm { //custom form constructor that takes main application form as a parameter public MdiForm1(Form1 parentForm) { InitializeComponent(); //these forms are child MDI windows, owned by the MDI container (main application form) this.MdiParent = parentForm; } }
Add BarManager components to both parent and child MDI windows. Create main menus, status and regular bars, then populate them.
Run the application to see the main menus merging automatically.
- BarManagers merge immediately after the application starts. To change this behavior and force BarManagers to merge only when a child window activates or maximizes, utilize the BarManager.MdiMenuMergeStyle property for the parent manager. Using the same property, you can also turn bar merging off.
There are now two “Help” sub-menus, one belongs to the parent main menu, the second belongs to the child main menu.
You have an option to combine such items. To do so, you need to set the BarItem.MergeType properties of both items to BarMenuMerge.MergeItems. Captions of both items also have to be absolutely identical (including the hidden “&” character).
Using the same property, you can exclude specific links from merging or make one link replace another in case both links have the same captions.
Parent and child toolbar links are arranged in the same order these links were in their original toolbars. To re-arrange these links, utilize the BarItem.MergeOrder property.
Merge Regular and Status Bars
Handle the parent BarManager’s BarManager.Merge and BarManager.UnMerge events and run the application. If you have left the BarManager.MdiMenuMergeStyle property in its default Always value, regular and status toolbars of child MDI forms will now be hidden.
This behavior is caused by the BarManager.HideBarsWhenMerging property. If you want your child toolbars to remain visible without merging, set this property for child Managers to false.
In the BarManager.Merge event handler, call the Bar.Merge method for a parent toolbar to populate it with item links of a specific child toolbar. Bar Managers merge toolbars by copying item links from one existing toolbar to another, you cannot make an entire toolbar swap its owners. Moreover, each bar can merge with one child toolbar only. With that being said, for every child toolbar merged you have to create a corresponding host toolbar in a parent Bar Manager. If a parent Manager has no fitting toolbars, you can either create fake toolbars dynamically on the BarManager.Merge event…
private void BarManager1_Merge(object sender, DevExpress.XtraBars.BarManagerMergeEventArgs e) { var parentBM = sender as BarManager; parentBM.BeginUpdate(); Bar tempBar1 = new Bar() { BarName = "tempBar1", Text = "tempBar1", DockStyle = BarDockStyle.Top, DockRow = parentBM.Bars["Tools"].DockRow, DockCol = 2 }; Bar tempBar2 = new Bar() { BarName = "tempBar2", Text = "tempBar2", DockStyle = BarDockStyle.Top, DockRow = parentBM.Bars["Tools"].DockRow, DockCol = 3 }; parentBM.Bars.AddRange(new Bar[] { tempBar1, tempBar2 }); parentBM.Bars["tempBar1"].Merge(e.ChildManager.Bars["barEdit"]); parentBM.Bars["tempBar2"].Merge(e.ChildManager.Bars["barFormat"]); parentBM.StatusBar.Merge(e.ChildManager.StatusBar); parentBM.EndUpdate(); }
…or add blank invisible toolbars at design time and make them visible when they receive item links from child toolbars.
private void BarManager1_Merge(object sender, DevExpress.XtraBars.BarManagerMergeEventArgs e) { var parentBM = sender as BarManager; parentBM.BeginUpdate(); parentBM.Bars["barEmpty"].Merge(e.ChildManager.Bars["barEdit"]); parentBM.Bars["barEmpty2"].Merge(e.ChildManager.Bars["barFormat"]); parentBM.Bars["barEmpty"].Visible = parentBM.Bars["barEmpty2"].Visible = true; parentBM.StatusBar.Merge(e.ChildManager.StatusBar); parentBM.EndUpdate(); }
Tip
In this and the following steps, bars are accessed by their internal names. To assign a meaningful name to a bar, utilize the Bar.BarName property.
To allow toolbars to undo your manual merging when needed, call the Bar.UnMerge method on the BarManager.UnMerge event. The UnMerge method takes no parameters, it returns all merged item links back to their original owners. Depending on whether you have created host parent toolbars at design time or dynamically at runtime, you will need to hide these toolbars or dispose of them respectively.
// unmerge toolbars created at design-time private void BarManager1_UnMerge(object sender, DevExpress.XtraBars.BarManagerMergeEventArgs e) { var parentBM = sender as BarManager; parentBM.BeginUpdate(); parentBM.Bars["barEmpty"].UnMerge(); parentBM.Bars["barEmpty2"].UnMerge(); parentBM.Bars["barEmpty"].Visible = false; parentBM.Bars["barEmpty2"].Visible = false; parentBM.StatusBar.UnMerge(); parentBM.EndUpdate(); } // unmerge toolbars created dynamically at runtime private void BarManager1_UnMerge(object sender, DevExpress.XtraBars.BarManagerMergeEventArgs e) { var parentBM = sender as BarManager; parentBM.BeginUpdate(); parentBM.Bars["tempBar1"].UnMerge(); parentBM.Bars["tempBar2"].UnMerge(); parentBM.Bars["tempBar1"].Dispose(); parentBM.Bars["tempBar2"].Dispose(); parentBM.StatusBar.UnMerge(); parentBM.EndUpdate(); }
After both Merge and Unmerge event handlers are ready, run the application to see the result.
Same as for main menus, you can utilize the BarItem.MergeType and BarItem.MergeOrder properties to customize and re-arrange merged items.
Application UI Manager Merging Specifics
The Application UI Manager, a component for building advanced multi-document interfaces, provides the DocumentManager.RibbonAndBarsMergeStyle property. When this property equals RibbonAndBarsMergeStyle.Default, merging is entirely managed by a parent Bar Manager and its BarManager.MdiMenuMergeStyle setting. Other property values affect the merging outcome as follows.
In Tabbed View.
DocumentManager.RibbonAndBarsMergeStyle = WhenNotFloating | ||
BarManager.MdiMenuMergeStyle = Always | Any currently active Document merges its toolbars. | Only toolbars from active tabs merge. |
BarManager.MdiMenuMergeStyle = OnlyWhenChildMaximized | Toolbars do not merge. | |
BarManager.MdiMenuMergeStyle = WhenChildActivated | Any currently active Document merges its toolbars. | Only toolbars from active tabs merge. |
BarManager.MdiMenuMergeStyle = Never | Toolbars do not merge |
In Native MDI View.
DocumentManager.RibbonAndBarsMergeStyle = WhenNotFloating | ||
BarManager.MdiMenuMergeStyle = Always | Toolbars from any active MDI window merge. | |
BarManager.MdiMenuMergeStyle = OnlyWhenChildMaximized | Toolbars do not merge. | |
BarManager.MdiMenuMergeStyle = WhenChildActivated | Toolbars from any active MDI window merge. | |
BarManager.MdiMenuMergeStyle = Never | Toolbars do not merge |