Search code examples
c#wpfdrag-and-drophittest

How to pass the hitTest through a control while performing a drag&drop operation


I have a tab control which allows me to drag the tab items out of my application.
This dragging will open a new window which will follow the mouse until I release the left mouse button.
Also it is possible to drag the tab item back into the source tab control and reattach it to its former parent or to any other control capable of understanding the dragged data.

private static void DragOutTabControl_PreviewQueryContinueDrag(object sender, QueryContinueDragEventArgs e)
{
   e.Handled = true;

   if (DragControlIsHit)
   {
      if (_previewWindow != null && _previewWindow.IsVisible)
      {
         _previewWindow.Clear();
         _previewWindow.Hide();
      }
   }
   else
   {
      if (_previewWindow == null)
      {
         _previewWindow = new PreviewWindow();
         _previewWindow.SetData();
      }

      _previewWindow.Left = CursorPos.X - 15;
      _previewWindow.Top = CursorPos.Y - 15;
      _previewWindow.Show();
   }
}

The problem I am having now is that when the preview window is following the mouse it is positioned directly under the cursor.
This way the dragEnter and dragOver events of the source tab control are not firing since the window is blocking the hit testing.
Even if I set IsHitTestVisible to false in the window the hit test will be blocked while the drag&drop is still active.
Setting IsEnabled to false and changing the background to null does not have any effect.

public PreviewWindow()
{
   Background = null;
   IsEnabled = false;
   IsHitTestVisible = false;
}

Is there any possibility to hide the preview window from any hit tests or to pass the hit test manually to any control visually behind the dragged window?

Edit, some more information to my problem:
I don't only want to drag tab items out of my tab control and open new windows for them, but also I want to be able to drag additional tab items into existing drag-out-windows.
Additionally dragging a tab item back into the original tab control should be possible.

All of this is working quite well except for the only problem that I can't hide the preview window from drag&drop-hittesting.


Solution

  • I had a similar question about DragDrop event hit testing, and the answer I received was to switch to using MouseEvents instead of DragDrop events. I made the switch and never regretted it, nor have I ever tried going back to WPF's built-in DragDrop events.

    As an alternative if you don't want to use use Mouse Events, would be to show your window on the Adorner Layer instead of the UI layer, and only render it as a new object once the Drop event occurs.