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