Search code examples
wpfdrag-and-dropright-clickwpf-textbox

TextBox - Drag and Drop with Right mouse


I'm trying to implement text swapping between 2 TextBoxes. Idea is, you have few of them and as you right-click on one of them, drag and drop on a different one and Text from the 1st one goes to 2nd one, and Text from 2nd one goes to the 1st one. So basically Text swap (Actually later I want to swap font name, size, etc... but one step at the time).

So problem I have is regarding RightClick handlers... By default on right click ContextMenu was showing up so I disabled it (by doing ContextMenu="{x:Null}"). I already know that adding handlers to MouseRightButtonDown not gonna work so I'm adding it to PreviewMouseRightButtonDown and C# code for it looks like that:

private void PreviewMouseRightButtonDownHandler(object sender, MouseButtonEventArgs e)
{
    DragDrop.DoDragDrop( e.Source as DependencyObject,
                         (sender as Textbox).Text,
                         DragDropEffects.Move);
}

Now when I press right mouse button over my TextBox this function is executed. Unfortunatelly as soon as I move my mouse a bit Text is getting pasted to the same TextBox :/ And I don't understand why... If I use PreviewMouseLeftButtonDown it's not behaving in same way and I'm able to drag mouse cursor out of TextBox.


I found similar question in here => WPF DragDrop.DoDragDrop (for a RIGHT-Click?) and was trying to add DragDrop.AddQueryContinueDragHandler(this, QueryContinueDragHandler); bit in my code but that doesn't seem to work :/ Also it's been like 5 years since then so maybe something has changed since then.

Anyone?


Solution

  • I do not know how you add the QueryContinueDragHandler (maybe by code?) but in this way "right button d&d" works for me (of course I got inspired by the question you linked)

    In the XAML:

    <StackPanel Orientation="Vertical">
        <TextBox Margin="10"
                    PreviewMouseRightButtonDown="PreviewMouseRightButtonDownHandler"
                    DragDrop.PreviewQueryContinueDrag="QueryContinueDragHandler" />
        <TextBox Margin="10" Text="Drag me"
                    PreviewMouseRightButtonDown="PreviewMouseRightButtonDownHandler"
                    DragDrop.PreviewQueryContinueDrag="QueryContinueDragHandler" />
    </StackPanel>
    

    And in the code behind:

    private void PreviewMouseRightButtonDownHandler(object sender, MouseButtonEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (textBox != null)
        {
            DragDrop.DoDragDrop(e.Source as DependencyObject,
                textBox.Text, DragDropEffects.Move);
    
            e.Handled = true;
        }
    }
    private void QueryContinueDragHandler(object source, QueryContinueDragEventArgs e)
    {
        TextBox textBox = source as TextBox;
    
        e.Handled = true;
    
        if (e.EscapePressed)
        {
            e.Action = DragAction.Cancel;
            return;
        }            
    
        if ((e.KeyStates & DragDropKeyStates.LeftMouseButton) != DragDropKeyStates.None)
        {
            e.Action = DragAction.Continue;
            return;
        }
    
        if ((e.KeyStates & DragDropKeyStates.RightMouseButton) != DragDropKeyStates.None)
        {
            e.Action = DragAction.Continue;
            return;
        }
    
        e.Action = DragAction.Drop;
    
        if (textBox != null)
        {
            textBox.Text = String.Empty;
        }
    }
    

    I hope it can help you.