How to dock a control with tabbed style into another control through docking context menu in WinForms Docking Manager?
Context menu event
DockContextMenu event will provide the facility to add a customized context menu into the docking context menu during run time. DockContextMenu event triggers when we right click on the caption bar of the docking window. DockContextMenuEventArgs provides the values of source control and Context menu.
Before we add a new ParentBarItem into the context menu, some important points to observe regarding controls that should not be added into the available controls list for docking as tabbed style are:
1. Controls docked with the source control.
2. Controls in Hidden state.
3. If the source control has the FloatOnly property to true, it should not redocked to the main form. So, we need not add the new menu into the context menu.
Following code snippet is used to add the new parent bar item with the collection of available controls list for docking with tabbed style.
C#
private void dockingManager1_DockContextMenu(object sender, Syncfusion.Windows.Forms.Tools.DockContextMenuEventArgs arg)
{
//Stores the source control
tempControl=arg.Owner;
//Get all sibiling controls into the SibilingContolsList array
this.GetSibilingControls(arg.Owner);
//flag for whether should add the control into the context menu or not
bool addThisControl=false;
//Get collection of currently docked controls under the docking manager
IEnumerator ienum = this.dockingManager1.Controls;
ArrayList dockedctrls = new ArrayList();
while(ienum.MoveNext())
dockedctrls.Add(ienum.Current);
//Initialize the Parentbar Item
ParentBarItem DockTabGroup= new ParentBarItem("TabbedWith..");
//Get the collection of BarItem into the ParenBar Item
foreach(Control ctrl in dockedctrls)
{
addThisControl=true;
//Checks whether the control is in the current source tabbed group
foreach(Control control in this.SibilingControlsList)
{
if(ctrl==control)
{
addThisControl=false;
break;
}
}
//Initializes the baritem and click event for each control
if(addThisControl&&!this.dockingManager1.GetFloatOnly(arg.Owner))
{
//We should check the control which is being to add in the ParentbarItem should not same as source control
//and also it should be visibled control.
if(ctrl!=arg.Owner && this.dockingManager1.GetDockVisibility(ctrl))
{
BarItem panelBar=new BarItem(ctrl.Name);
panelBar.Click+=new EventHandler(panelBar_Click);
DockTabGroup.Items.Add(panelBar);
}
}
}
//Added the parent bar Item into the DockContextMenu, if items count is more than 0
if(DockTabGroup.Items.Count>0)
{
//Get the context menu
PopupMenu menu = arg.ContextMenu;
//Add the DockTabGroup parent baritem into the DockTo parent baritem
foreach(BarItem b in menu.ParentBarItem.Items)
{
if(b.Text=="Dock to")
{
ParentBarItem pb=(ParentBarItem)b;
//Add new parent bar item
pb.Items.Add(DockTabGroup);
}
}
}
//Clear the list of sibiling controls
this.SibilingControlsList.Clear();
}
//This event will trigger when we click on the panel bar
private void panelBar_Click(object sender, EventArgs e)
{
IEnumerator ienum = this.dockingManager1.Controls;
ArrayList dockedctrls = new ArrayList();
string CurrentControlName=((BarItem)sender).Text;
while(ienum.MoveNext())
dockedctrls.Add(ienum.Current);
//Dock as the tabbed group with the target control
foreach(Control ctrl in dockedctrls)
{
if(ctrl.Name==CurrentControlName)
//Docks a source control into a specified parent control
this.dockingManager1.DockControl(tempControl,ctrl,DockingStyle.Tabbed,ctrl.Width,true);
}
}
VB
Private Sub dockingManager1_DockContextMenu(ByVal sender As Object, ByVal arg As Syncfusion.Windows.Forms.Tools.DockContextMenuEventArgs) Handles dockingManager1.DockContextMenu
'Stores the source control
tempControl=arg.Owner
'Get all sibiling controls into the SibilingContolsList array
Me.GetSibilingControls(arg.Owner)
'flag for whether should add the control into the context menu or not
Dim addThisControl As Boolean=False
'Get collection of currently docked controls under the docking manager
Dim ienum As IEnumerator = Me.dockingManager1.Controls
Dim dockedctrls As ArrayList = New ArrayList()
Do While ienum.MoveNext()
dockedctrls.Add(ienum.Current)
Loop
'Initialize the Parentbar Item
Dim DockTabGroup As ParentBarItem= New ParentBarItem("TabbedWith..")
'Get the collection of BarItem into the ParenBar Item
For Each ctrl As Control In dockedctrls
addThisControl=True
'Checks whether the control is in the current source tabbed group
For Each control As Control In Me.SibilingControlsList
If ctrl Is control Then
addThisControl=False
Exit For
End If
Next control
'Initializes the baritem and click event for each control
If addThisControl AndAlso (Not Me.dockingManager1.GetFloatOnly(arg.Owner)) Then
'We should check the control which is being to add in the ParentbarItem should not same as source control
'and also it should be visibled control.
If Not ctrl Is arg.Owner AndAlso Me.dockingManager1.GetDockVisibility(ctrl) Then
Dim panelBar As BarItem = New BarItem(ctrl.Name)
AddHandler panelBar.Click, AddressOf panelBar_Click
DockTabGroup.Items.Add(panelBar)
End If
End If
Next ctrl
'Added the parent bar Item into the DockContextMenu, if items count is more than 0
If DockTabGroup.Items.Count>0 Then
'Get the context menu
Dim menu As PopupMenu = arg.ContextMenu
'Add the DockTabGroup parent baritem into the DockTo parent baritem
For Each b As BarItem In menu.ParentBarItem.Items
If b.Text="Dock to" Then
Dim pb As ParentBarItem=CType(b, ParentBarItem)
'Add new parent bar item
pb.Items.Add(DockTabGroup)
End If
Next b
End If
'Clear the list of sibiling controls
Me.SibilingControlsList.Clear()
End Sub
'This event will trigger when we click on the panel bar
Private Sub panelBar_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim ienum As IEnumerator = Me.dockingManager1.Controls
Dim dockedctrls As ArrayList = New ArrayList()
Dim CurrentControlName As String=(CType(sender, BarItem)).Text
Do While ienum.MoveNext()
dockedctrls.Add(ienum.Current)
Loop
'Dock as the tabbed group with the target control
For Each ctrl As Control In dockedctrls
If ctrl.Name=CurrentControlName Then
'Docks a source control into a specified parent control
Me.dockingManager1.DockControl(tempControl,ctrl,DockingStyle.Tabbed,ctrl.Width,True)
End If
Next ctrl
End Sub
Get Sibling controls
There is no direct API to determine the tabbed state, but this can be easily accomplished by accessing some of the internal docking windows classes. The following code tests whether the dockable control ’ctrl’ is in a tabbed dock group, and if so, add all the controls into the group.
C#
//Collects the list of sibiling controls connected with the source control
public void GetSibilingControls(Control ctrl)
{
//Host form created by list box parent control
Syncfusion.Windows.Forms.Tools.DockHost dhost = ctrl.Parent as Syncfusion.Windows.Forms.Tools.DockHost;
Syncfusion.Windows.Forms.Tools.DockHostController dhc = dhost.InternalController as Syncfusion.Windows.Forms.Tools.DockHostController;
//This statement checks whether the control within the tab control or not
if(dhc.ParentController is Syncfusion.Windows.Forms.Tools.DockTabController)
{
Syncfusion.Windows.Forms.Tools.DockTabControl docktab = (dhc.ParentController as Syncfusion.Windows.Forms.Tools.DockTabController).TabControl;
//Here the code will add the list of child control which are grouped with the source control.
foreach(Syncfusion.Windows.Forms.Tools.DockTabPage tabpage in docktab.TabPages)
{
this.SibilingControlsList.Add( tabpage.dhcClient.HostControl.Controls[0]);
}
}
}
VB
'Collects the list of sibiling controls connected with the source control 'Collects the list of sibiling controls connected with the source control Public Sub GetSibilingControls(ByVal ctrl As Control) 'Host form created by list box parent control Dim dhost As Syncfusion.Windows.Forms.Tools.DockHost = CType(ctrl.Parent, Syncfusion.Windows.Forms.Tools.DockHost) Dim dhc As Syncfusion.Windows.Forms.Tools.DockHostController = CType(dhost.InternalController, Syncfusion.Windows.Forms.Tools.DockHostController) 'This statement checks whether the control within the tab control or not If TypeOf dhc.ParentController Is Syncfusion.Windows.Forms.Tools.DockTabController Then Dim docktab As Syncfusion.Windows.Forms.Tools.DockTabControl = CType(dhc.ParentController, Syncfusion.Windows.Forms.Tools.DockTabController).TabControl 'Here the code will add the list of child control which are grouped with the source control. For Each tabpage As Syncfusion.Windows.Forms.Tools.DockTabPage In docktab.TabPages Me.SibilingControlsList.Add(tabpage.dhcClient.HostControl.Controls(0)) Next tabpage End If End Sub
UG document link: https://help.syncfusion.com/windowsforms/dockingmanager/docking-events#context-menu