I have two TabControls and I've implemented the ability to drag and drop tabpages between the two controls. It works great until you drag the last tabpage off one of the controls. The control then stops accepting drops and I can't put any tabpages back on that control.
The drag and drop code for one direction is below. The reverse direction is the same with the control names swapped.
// Source TabControl
private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.tabControl1.DoDragDrop(this.tabControl1.SelectedTab, DragDropEffects.All);
}
//Target TabControl
private void tabControl2_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(TabPage)))
e.Effect = DragDropEffects.Move;
else
e.Effect = DragDropEffects.None;
}
private void tabControl2_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
TabPage DropTab = (TabPage)(e.Data.GetData(typeof(TabPage)));
if (tabControl2.SelectedTab != DropTab)
this.tabControl2.TabPages.Add (DropTab);
}
You need to override WndProc
in the TabControl and turn HTTRANSPARENT
into HTCLIENT
in the WM_NCHITTEST
message.
For example:
const int WM_NCHITTEST = 0x0084;
const int HTTRANSPARENT = -1;
const int HTCLIENT = 1;
//The default hit-test for a TabControl's
//background is HTTRANSPARENT, preventing
//me from receiving mouse and drag events
//over the background. I catch this and
//replace HTTRANSPARENT with HTCLIENT to
//allow the user to drag over us when we
//have no TabPages.
protected override void WndProc(ref Message m) {
base.WndProc(ref m);
if (m.Msg == WM_NCHITTEST) {
if (m.Result.ToInt32() == HTTRANSPARENT)
m.Result = new IntPtr(HTCLIENT);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With