Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinForms TabControl drag drop problem

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); 
}
like image 394
Kevin Gale Avatar asked Feb 21 '11 20:02

Kevin Gale


1 Answers

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);
    }
}
like image 68
SLaks Avatar answered Oct 09 '22 20:10

SLaks