FlyingHubert
FlyingHubert

Reputation: 35

Drag'n'Drop in WPF app throws InvalidOperationException

I've tried many times now to get Drag'n'Drop working in my C# WPF Applications without using nuget packages. But I cannot manage to get even the simplest example running.

My current try involves a simple test UI with just 2 Textboxes and I want to drag'n'drop the text from one Textbox to the other one.

This is the UI I created ... just 2 Textboxes sitting in a Window.

<Window x:Class="DragAndDropExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DragAndDropExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>
        
        <TextBox x:Name="DragSource" Grid.Row="0" 
                 Background="LightGray" Height="50" Margin="10" MouseMove="DragSource_MouseMove" PreviewMouseMove="DragSource_MouseMove"/>
        <TextBox x:Name="DropTarget" Grid.Row="1" AllowDrop="True" Drop="DropTarget_Drop"
                 Background="LightGray" Height="50" Margin="10"/>
    </Grid>
</Window>

The code behind looks like this

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace DragAndDropExample
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void DragSource_MouseMove(object sender, MouseEventArgs e)
        {
            var textBox = sender as TextBox;
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                var data = new DataObject(DataFormats.StringFormat, textBox.Text);
                DragDrop.DoDragDrop(textBox, data, DragDropEffects.Copy); // Here the exception occurs
            }
        }

        private void DropTarget_Drop(object sender, DragEventArgs e)
        {
            var textBox = sender as TextBox;
            var data = e.Data;

            if (data.GetDataPresent(DataFormats.StringFormat))
            {
                textBox.Text += data.GetData(DataFormats.StringFormat);
            }
        }
    }
}

I mean this code is pretty simple and I thought I would have the chance to get it running but even googling the exception doesn't bring me to an conclusive answer.

There are suggetions like using the dispatcher. But that first of all didnt work for me and second doesn't seem to be a good answer for such a trivial problem.

Maybe there is someout out there who can help me with this one.

Greetings Lukas

Upvotes: 1

Views: 634

Answers (1)

Klaus G&#252;tter
Klaus G&#252;tter

Reputation: 11977

The problem here is that the TextBox itself does its own stuff on MouseMove (e.g. selection) and DoDragDrop is interfering with it.

If you just want to experiment with Drag&Drop, you might use some other area of the window to initiate the drag, e.g.

<Window x:Class="DragAndDropExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DragAndDropExample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>

        <TextBox x:Name="DragSource" Grid.Row="0" 
                 Background="LightGray" Height="50" Margin="10" />
        <Rectangle Grid.Row="0" Grid.Column="1" Height="40" Width="40" MouseMove="DragSource_MouseMove" Fill="Blue"/>
        <TextBox x:Name="DropTarget" Grid.Row="1" AllowDrop="True" Drop="DropTarget_Drop"
                 Background="LightGray" Height="50" Margin="10"/>
    </Grid>
</Window>

private void DragSource_MouseMove(object sender, MouseEventArgs e)
{
  base.OnMouseMove(e);
  var textBox = DragSource;
  if (e.LeftButton == MouseButtonState.Pressed)
  {
    var data = new DataObject(DataFormats.StringFormat, textBox.Text);
    DragDrop.DoDragDrop(textBox, data, DragDropEffects.Copy); // Here the exception occurs
  }
}

BTW: Dragging text from one text box to another works out of the box.

Upvotes: 1

Related Questions