Ribbon Merge in WPF Ribbon
9 Aug 202324 minutes to read
WPF Ribbon allows merging of RibbonTab and RibbonBar of two different Ribbon controls in MDI applications. DocumentContainer.MDIParentRibbon, RibbonTab.MergeType and RibbonTab.MergeOrder properties helps to perform menu merging.
In WPF, you can create MDI application using DocumentContainer control. Also, Ribbon controls allows to merge RibbonTab and RibbonBar of active child window to the Ribbon in parent window.
Creating MDI window and enabling menu merging
DocumentContainer helps to create MDI window in WPF Application. The DocumentContainer allows you to create MDI window and Tabbed MDI window layouts.
Follow the below steps to create simple sample to understand ribbon menu merging,
- Creating main RibbonWindow with Ribbon and DocumentContainer
<syncfusion:RibbonWindow xmlns:syncfusion="http://schemas.syncfusion.com/wpf" x:Class="Ribbon.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ribbon"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
xmlns:skin="clr-namespace:Syncfusion.SfSkinManager;assembly=Syncfusion.SfSkinManager.WPF"
skin:SfSkinManager.VisualStyle="Office2019Colorful"
Title="Ribbon Merging" Height="450" Width="700">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<syncfusion:Ribbon x:Name="parentRibbon" >
<syncfusion:RibbonTab Caption="Home">
<syncfusion:RibbonBar Header="Mail">
<syncfusion:RibbonButton Label="New Mail" SizeForm="Large" Click="RibbonButton_Click"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
</syncfusion:Ribbon>
<syncfusion:DocumentContainer x:Name="doc" Grid.Row="1" >
</syncfusion:DocumentContainer>
</Grid>
</syncfusion:RibbonWindow>
- Next, lets create two
UserControl
views with Ribbon which acts as child MDI windows.
Child View 1
<UserControl x:Class="Ribbon.ChildView1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Ribbon"
mc:Ignorable="d" xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<ContentPresenter>
<ContentPresenter.Content>
<Grid>
<syncfusion:Ribbon x:Name="childRibbon" >
<syncfusion:RibbonTab Caption="Home" MergeType="MergeItems">
<syncfusion:RibbonBar Header="Message">
<syncfusion:RibbonButton Label="New Message" SizeForm="Large"/>
<syncfusion:RibbonButton x:Name="MergeButton" Label="Merge" SizeForm="Large" />
<syncfusion:RibbonButton x:Name="UnMergeButton" Label="UnMerge" SizeForm="Large"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
<syncfusion:RibbonTab Caption="View1 Tab2" >
<syncfusion:RibbonBar Header="Folders">
<syncfusion:RibbonButton Label="New Folder" SizeForm="Large"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
</syncfusion:Ribbon>
<TextBlock Text="View 1"/>
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</UserControl>
Child View 2
<UserControl x:Class="Ribbon.ChildView2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Ribbon"
mc:Ignorable="d" xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<ContentPresenter>
<ContentPresenter.Content>
<Grid>
<syncfusion:Ribbon x:Name="childRibbon" >
<syncfusion:RibbonTab Caption="View2 Home" MergeType="AddItems">
<syncfusion:RibbonBar Header="Message">
<syncfusion:RibbonButton Label="View Message" SizeForm="Large"/>
<syncfusion:RibbonButton x:Name="MergeButton" Label="Merge" SizeForm="Large" />
<syncfusion:RibbonButton x:Name="UnMergeButton" Label="UnMerge" SizeForm="Large"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
<syncfusion:RibbonTab Caption="View2 Tab2" MergeOrder="1">
<syncfusion:RibbonBar Header="Folders">
<syncfusion:RibbonButton Label="New Folder" SizeForm="Large"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
</syncfusion:Ribbon>
<TextBlock Text="View 2"/>
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</UserControl>
- Now, add the both child view’s into the DocumentContainer and set the the DocumentContainer.MDIParentRibbon property of DocumentContainer.
<syncfusion:RibbonWindow xmlns:syncfusion="http://schemas.syncfusion.com/wpf" x:Class="Ribbon.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ribbon"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
xmlns:skin="clr-namespace:Syncfusion.SfSkinManager;assembly=Syncfusion.SfSkinManager.WPF"
skin:SfSkinManager.VisualStyle="Office2019Colorful"
Title="Ribbon Merging" Height="450" Width="700">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<syncfusion:Ribbon x:Name="parentRibbon" >
<syncfusion:RibbonTab Caption="Home">
<syncfusion:RibbonBar Header="Mail">
<syncfusion:RibbonButton Label="New Mail" SizeForm="Large" Click="RibbonButton_Click"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
</syncfusion:Ribbon>
<syncfusion:DocumentContainer x:Name="doc" Grid.Row="1" MDIParentRibbon="{Binding ElementName=parentRibbon}">
<local:ChildView1 x:Name="ChildView1" syncfusion:DocumentContainer.Header="Child View1" syncfusion:DocumentContainer.MDIBounds="150,50,300,230"/>
<local:ChildView2 x:Name="ChildView2" syncfusion:DocumentContainer.Header="Child View2" syncfusion:DocumentContainer.MDIBounds="20,10,300,230"/>
</syncfusion:DocumentContainer>
</Grid>
</syncfusion:RibbonWindow>
Now run the application and you can see an output like this.
-
Now the child view’s has been added inside the DocumentContainer, and now lets see how to merge the child Ribbon into the parent Ribbon.
The merging operation performed based on DocumentContainer.Mode (
MDI
andTDI
) property.
- MDI - The default value of DocumentContainer.Mode. In the above image child view’s are in MDI mode where each view loaded inside a child window. You can merge the Ribbon in child view’s into the MDI parent Ribbon by maximizing the MDI child window.
- TDI - The child view’s will be loaded in tabs. In this mode, the child view’s ribbon of the active tab will be merged to the MDI parent Ribbon.
In the below example the DocumentContainer.Mode property for DocumentContainer is set to TDI.
<syncfusion:RibbonWindow xmlns:syncfusion="http://schemas.syncfusion.com/wpf" x:Class="Ribbon.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Ribbon"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
xmlns:skin="clr-namespace:Syncfusion.SfSkinManager;assembly=Syncfusion.SfSkinManager.WPF"
skin:SfSkinManager.VisualStyle="Office2019Colorful"
Title="Ribbon Merging" Height="450" Width="450">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<syncfusion:Ribbon x:Name="parentRibbon" >
<syncfusion:RibbonTab Caption="Home">
<syncfusion:RibbonBar Header="Mail">
<syncfusion:RibbonButton Label="New Mail" SizeForm="Large" Click="RibbonButton_Click"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
</syncfusion:Ribbon>
<syncfusion:DocumentContainer x:Name="doc" Grid.Row="1" MDIParentRibbon="{Binding ElementName=parentRibbon}" Mode="TDI">
<local:ChildView1 x:Name="ChildView1" syncfusion:DocumentContainer.Header="Child View1" syncfusion:DocumentContainer.MDIBounds="150,50,300,230"/>
<local:ChildView2 x:Name="ChildView2" syncfusion:DocumentContainer.Header="Child View2" syncfusion:DocumentContainer.MDIBounds="20,10,300,230"/>
</syncfusion:DocumentContainer>
</Grid>
</syncfusion:RibbonWindow>
In the image notice that Child View1
tab is selected and elements of selected child view’s ribbon are merged into the MDI parent Ribbon.
NOTE
Merge Type
RibbonTab.MergeType property indicates how the items in child view’s ribbon are merged with MDI parent ribbon. MergeType has following options,
-
Add - Adds the child view’s RibbonTab to the MDI parent ribbon based on RibbonTab.MergeOrder, even if MDI parent has RibbonTab with same Caption.
-
Merge - The default value of RibbonTab.MergeType. If RibbonTab.Caption of MDI parent ribbon and RibbonTab.Caption of child view’s ribbon has same name and child view’s RibbonTab.MergeType is Merge, then child view’s RibbonBar’s are merged with MDI parent’s tab. If MDI parent ribbon doesn’t have tab with same caption, then child view’s ribbon tab added to MDI parent ribbon based on RibbonTab.MergeOrder.
Let’s look at the example,
In the example both the MDI parent ribbon and child view1’s ribbon has ribbon tab with same caption and the default value of MergeType is Merge. So, when child view1 maximized, bar’s in child view’s Home tab get are merged to MDI parent ribbon’s Home tab.
If you change the MergeType of ribbon tab in child view1 as Add
, then Home
tab will be added as new tab like View1 Tab2
NOTE
Merge Order
MDI parent ribbon positions the child view’s ribbon tabs followed by the tabs of MDI parent ribbon. You can change the position of child view’s ribbon using RibbonTab.MergeOrder property.
In the below code, the RibbonTab.MergeOrder for View2 Tab2
is set as 1. So, the ribbon tab is positioned at 1st index while merging to MDI parent.
<UserControl x:Class="Ribbon.ChildView2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Ribbon"
mc:Ignorable="d" xmlns:syncfusion="http://schemas.syncfusion.com/wpf"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<ContentPresenter>
<ContentPresenter.Content>
<Grid>
<syncfusion:Ribbon x:Name="childRibbon" >
<syncfusion:RibbonTab Caption="View2 Home" MergeType="AddItems">
<syncfusion:RibbonBar Header="Message">
<syncfusion:RibbonButton Label="View Message" SizeForm="Large"/>
<syncfusion:RibbonButton x:Name="MergeButton" Label="Merge" SizeForm="Large" />
<syncfusion:RibbonButton x:Name="UnMergeButton" Label="UnMerge" SizeForm="Large"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
<syncfusion:RibbonTab Caption="View2 Tab2" MergeOrder="1">
<syncfusion:RibbonBar Header="Folders">
<syncfusion:RibbonButton Label="New Folder" SizeForm="Large"/>
</syncfusion:RibbonBar>
</syncfusion:RibbonTab>
</syncfusion:Ribbon>
<TextBlock Text="View 2"/>
</Grid>
</ContentPresenter.Content>
</ContentPresenter>
</Grid>
</UserControl>
NOTE
Merging and Unmerging in code
Ribbon merging can be performed in code by using Ribbon.Merge method of MDI parent ribbon. Child view’s ribbon should be passed as parameter to perform merge operation.
Similarly, the child ribbon can be unmerged from MDI parent ribbon using Ribbon.UnMerge method of MDI parent ribbon.
public MainWindow()
{
InitializeComponent();
this.Child1.MergeButton.Click += MergeButton_Click;
this.Child1.UnMergeButton.Click += UnMergeButton_Click;
}
private void UnMergeButton_Click(object sender, RoutedEventArgs e)
{
this.parentRibbon.UnMerge(this.Child1.childRibbon);
}
private void MergeButton_Click(object sender, RoutedEventArgs e)
{
this.parentRibbon.Merge(this.Child1.childRibbon);
}
Public Sub New()
InitializeComponent()
Me.Child1.MergeButton.Click += AddressOf MergeButton_Click
Me.Child1.UnMergeButton.Click += AddressOf UnMergeButton_Click
End Sub
Private Sub UnMergeButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.parentRibbon.UnMerge(Me.Child1.childRibbon)
End Sub
Private Sub MergeButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.parentRibbon.Merge(Me.Child1.childRibbon)
End Sub