问题
I have several tabpages on a single tab control and I was wondering if anyone out there knows how I can program a way to drag tabpages off the tab control and into their own "form"....pulling the tabcontrol apart?
I'm using vb.net and did find many ways to move the order of tabpages on the tabcontrol but non om how to actually detach the tabpage and place \ drag it elsewhere on the screen?
回答1:
Assuming WinForms, essentially you have to create a new Form and a new TabControl to house the TabPage you plan on moving.
In its simplest form:
Private Sub TabControl1_MouseMove(sender As Object, e As MouseEventArgs) Handles TabControl1.MouseMove
If (e.Button = MouseButtons.Left) Then
TabControl1.DoDragDrop(TabControl1.SelectedTab, DragDropEffects.Move)
End If
End Sub
Private Sub TabControl1_GiveFeedback(sender As Object, e As GiveFeedbackEventArgs) Handles TabControl1.GiveFeedback
e.UseDefaultCursors = False
End Sub
Private Sub TabControl1_QueryContinueDrag(sender As Object, e As QueryContinueDragEventArgs) Handles TabControl1.QueryContinueDrag
If Control.MouseButtons <> MouseButtons.Left Then
e.Action = DragAction.Cancel
Dim f As New Form
f.Size = New Size(400, 300)
f.StartPosition = FormStartPosition.Manual
f.Location = MousePosition
Dim tc As New TabControl
tc.Dock = DockStyle.Fill
tc.TabPages.Add(TabControl1.SelectedTab)
f.Controls.Add(tc)
f.Show()
Me.Cursor = Cursors.Default
Else
e.Action = DragAction.Continue
Me.Cursor = Cursors.Help
End If
End Sub
回答2:
Here I'd like to submit my personal improvement based on LarsTech's code. This version allows the tab to go back to its original parent when the form closes and requires the user to drag the tab away by a defined offset of pixel before the drag event is triggered.
Dim pTabControlClickStartPosition As Point
Dim iTabControlFlyOffPixelOffset As Integer = 20
Private Sub TabControlMain_MouseDown(sender As Object, e As MouseEventArgs) Handles TabControlMain.MouseDown
If (e.Button = MouseButtons.Left) Then
pTabControlClickStartPosition = e.Location
End If
End Sub
Private Sub TabControlMain_MouseMove(sender As Object, e As MouseEventArgs) Handles TabControlMain.MouseMove
If (e.Button = MouseButtons.Left) Then
Dim iMouseOffset_X = pTabControlClickStartPosition.X - e.X
Dim iMouseOffset_Y = pTabControlClickStartPosition.Y - e.Y
If iMouseOffset_X > iTabControlFlyOffPixelOffset Or iMouseOffset_Y > iTabControlFlyOffPixelOffset Then
TabControlMain.DoDragDrop(TabControlMain.SelectedTab, DragDropEffects.Move)
pTabControlClickStartPosition = New Point
End If
Else
pTabControlClickStartPosition = New Point
End If
End Sub
Private Sub TabControlMain_GiveFeedback(sender As Object, e As GiveFeedbackEventArgs) Handles TabControlMain.GiveFeedback
e.UseDefaultCursors = False
End Sub
Private Sub TabControlMain_QueryContinueDrag(sender As Object, e As QueryContinueDragEventArgs) Handles TabControlMain.QueryContinueDrag
If Control.MouseButtons <> MouseButtons.Left Then
e.Action = DragAction.Cancel
Dim f As New Form
f.Size = New Size(800, 400)
f.StartPosition = FormStartPosition.Manual
f.Location = MousePosition
Dim tc As New TabControl
tc.Dock = DockStyle.Fill
tc.TabPages.Add(TabControlMain.SelectedTab)
f.Controls.Add(tc)
AddHandler f.FormClosing, Sub(sender1 As Object, e1 As EventArgs)
TabControlMain.TabPages.Add(tc.SelectedTab)
End Sub
f.Show()
Me.Cursor = Cursors.Default
Else
e.Action = DragAction.Continue
Me.Cursor = Cursors.SizeAll
End If
End Sub
UPDATE: As pointed out in the comments, when the child form is closed, the TabPage is put back in the original TabControl but not in the previous order.
To avoid this behaviour we can assign a priority to the TabPages using the Tag property.
Let's assume we have three TabPages in our TabControl in the order: "Tab C", "Tab A", Tab B". Now we have to set TabA.Tag = 2, TabB.Tag = 3, TabC.Tag = 1.
Then change f.FormClosing code into this:
'Get the first TabPage with a greater Tag value than the one being inserted.
Dim followingTab = TabControlMain.TabPages.Cast(Of TabPage)().FirstOrDefault(Function(tp) CInt(tp.Tag) > CInt(tc.SelectedTab.Tag))
If followingTab Is Nothing Then
'There is no following tab so add this one to the end.
TabControlMain.TabPages.Add(tc.SelectedTab)
Else
'Insert this tab before the following one.
TabControlMain.TabPages.Insert(TabControlMain.TabPages.IndexOf(followingTab), tc.SelectedTab)
End If
Source: http://www.vbforums.com/showthread.php?766367-Tabpage-Add-or-insert-tabpage-with-order-determined&s=1b895ca4d79ab29e7c00c4b07a4ce142&p=4692139&viewfull=1#post4692139
来源:https://stackoverflow.com/questions/22043318/drag-and-detach-tabpages