WPF 应用程序中的拖放操作抛出 InvalidOperationException

Drag'n'Drop in WPF app throws InvalidOperationException

我现在已经尝试过很多次在不使用 nuget 包的情况下让 Drag'n'Drop 在我的 C# WPF 应用程序中工作。但我连最简单的例子都搞不出来 运行.

我目前的尝试涉及一个简单的测试 UI,只有 2 个文本框,我想将文本从一个文本框拖放到另一个文本框。

这是我创建的 UI...只有 2 个文本框位于 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>

后面的代码是这样的

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);
            }
        }
    }
}

我的意思是这段代码非常简单,我想我有机会得到它 运行 但即使用谷歌搜索异常也不能给我一个结论性的答案。

有使用调度程序等建议。但首先对我没有用,其次似乎不是解决这样一个微不足道的问题的好答案。

也许有人可以帮我解决这个问题。

你好卢卡斯

这里的问题是 TextBox 本身在 MouseMove 上做自己的事情(例如选择),而 DoDragDrop 会干扰它。

如果您只想尝试拖放,您可以使用 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="*"/>
        </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
  }
}

顺便说一句:将文本从一个文本框拖到另一个文本框是开箱即用的。