【问题标题】:Drag'n'Drop in WPF app throws InvalidOperationExceptionWPF 应用程序中的 Drag'n'Drop 引发 InvalidOperationException
【发布时间】:2020-08-08 12:39:41
【问题描述】:

我现在已经多次尝试让 Drag'n'Drop 在我的 C# WPF 应用程序中工作,而无需使用 nuget 包。但即使是最简单的示例我也无法运行。

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

这是我创建的 UI ...只有 2 个文本框位于一个窗口中。

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

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

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

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

问候卢卡斯

【问题讨论】:

  • 为什么您的 MouseMove 处理程序调用 base.OnPreviewMouseMove?您还连接了 PreviewMouseMove 事件,但没有向我们显示事件处理程序。
  • 我的错 - 复制了错误的行(来自之前的尝试。会更正它。谢谢

标签: c# wpf drag-and-drop


【解决方案1】:

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

如果您只是想尝试拖放,您可以使用窗口的其他区域来启动拖动,例如

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

顺便说一句:将文本从一个文本框拖到另一个文本框即可。

【讨论】:

  • 感谢您的快速回复。首先 - 你的版本有效,因此我会测试一下,看看我的 std.拖放的用例将起作用。 (例如从一个列表到另一个列表)但是我对您对我的例外的回应并不特别满意。 这里的问题是 TextBox 本身在 MouseMove 上做自己的事情(例如选择),而 DoDragDrop 正在干扰它。 有什么地方出了问题是很清楚的,有一个例外,它必须使用文本框。但是为什么会出现问题,我可以解决它吗?
  • 好的 - 我尝试了其他一些控件,但当我认为文本框是一个简单的例子时,我似乎错了^^。其他控件工作得更顺畅。
猜你喜欢
  • 2010-09-24
  • 2021-05-21
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 1970-01-01
  • 2011-10-08
  • 1970-01-01
相关资源
最近更新 更多