Wpf:拖放到文本框

Wpf:拖放到文本框,wpf,textbox,drag-and-drop,Wpf,Textbox,Drag And Drop,我用谷歌搜索了这个问题,人们也回答了类似的问题,但由于某种原因,我什么都做不到。我一定是错过了什么。。。无论如何,当我运行以下代码时,永远不会调用TextBox\u DragEnter处理程序。但是,如果我将xaml中的TextBox元素更改为TextBlock元素,则会调用它。有没有办法从TextBox元素获得相同的行为?下面的代码完全隔离了问题 MainWindow.xaml: <Window x:Class="Wpf1.MainWindow" xmlns="http:

我用谷歌搜索了这个问题,人们也回答了类似的问题,但由于某种原因,我什么都做不到。我一定是错过了什么。。。无论如何,当我运行以下代码时,永远不会调用TextBox\u DragEnter处理程序。但是,如果我将xaml中的TextBox元素更改为TextBlock元素,则会调用它。有没有办法从TextBox元素获得相同的行为?下面的代码完全隔离了问题

MainWindow.xaml:

<Window x:Class="Wpf1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid Name="myGrid">
        <TextBox AllowDrop="True" PreviewDragEnter="TextBox_DragEnter" PreviewDrop="TextBox_Drop" />
    </Grid>
</Window>

MainWindow.xaml.cs:

using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Collections.ObjectModel;

namespace Wpf1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void TextBox_DragEnter(object sender, DragEventArgs e)
        {
            e.Effects = DragDropEffects.Copy;
        }

        private void TextBox_Drop(object sender, DragEventArgs e)
        {

        }
    }
}
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Input;
使用System.Collections.ObjectModel;
命名空间Wpf1
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
私有void文本框\u DragEnter(对象发送方,DragEventArgs e)
{
e、 效果=DragDropEffects.Copy;
}
私有无效文本框(对象发送方,DragEventArgs e)
{
}
}
}
非常感谢

安德鲁

编辑:

<i:Interaction.Triggers>
        <i:EventTrigger EventName="Drop">
            <cmd:EventToCommand Command="{Binding DragDropCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
        <i:EventTrigger EventName="PreviewDragOver">
            <cmd:EventToCommand Command="{Binding PreviewDragEnterCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
        <i:EventTrigger EventName="PreviewDragEnter">
            <cmd:EventToCommand Command="{Binding PreviewDragEnterCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
        private void ExecutePreviewDragEnterCommand(DragEventArgs drgevent)
        {
            drgevent.Handled = true;


            // Check that the data being dragged is a file
            if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Get an array with the filenames of the files being dragged
                string[] files = (string[])drgevent.Data.GetData(DataFormats.FileDrop);

                if ((String.Compare(System.IO.Path.GetExtension(files[0]), ".xls", true) == 0)
                    && files.Length == 1)
                    drgevent.Effects = DragDropEffects.Move;
                else
                    drgevent.Effects = DragDropEffects.None;

            }
            else
                drgevent.Effects = DragDropEffects.None;
        }

为了澄清,我想允许将自定义对象拖放到文本框中。在textbox的Drop处理程序中,我想将textbox的文本设置为对象中的属性,然后将textbox的IsReadOnly属性设置为false。我只是在为文本框启用拖放功能时遇到了一些问题…

如果为PreviewDragOver添加处理程序,则将e.Handled=true设置为有效


在任何情况下都适用于我。

TextBox
似乎已经对DragAndDrop进行了一些默认处理。如果您的数据对象是一个字符串,那么它就可以简单地工作。其他类型不会被处理,你会得到禁止鼠标效果,你的放置处理程序也不会被调用

似乎您可以在
PreviewDragOver
事件处理程序中使用
e.Handled
启用自己的处理

我在MSDN上找不到任何细节,但是
发现非常有用。

您可能还希望以与PreviewDragOver相同的方式处理PreviewDragEnter,否则它将默认在第一个像素上使用禁止的鼠标

在处理程序中,确保DragEventArgs.Data是要删除的类型。如果是,请将DragEventsArgs.Effects设置为DragDropEffects.Move或AllowedEffects中的其他内容。如果不是要删除的类型,请设置为DragDropEffects.None,这将禁用删除

MVVM灯光的XAML:

<i:Interaction.Triggers>
        <i:EventTrigger EventName="Drop">
            <cmd:EventToCommand Command="{Binding DragDropCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
        <i:EventTrigger EventName="PreviewDragOver">
            <cmd:EventToCommand Command="{Binding PreviewDragEnterCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
        <i:EventTrigger EventName="PreviewDragEnter">
            <cmd:EventToCommand Command="{Binding PreviewDragEnterCommand}" PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
        private void ExecutePreviewDragEnterCommand(DragEventArgs drgevent)
        {
            drgevent.Handled = true;


            // Check that the data being dragged is a file
            if (drgevent.Data.GetDataPresent(DataFormats.FileDrop))
            {
                // Get an array with the filenames of the files being dragged
                string[] files = (string[])drgevent.Data.GetData(DataFormats.FileDrop);

                if ((String.Compare(System.IO.Path.GetExtension(files[0]), ".xls", true) == 0)
                    && files.Length == 1)
                    drgevent.Effects = DragDropEffects.Move;
                else
                    drgevent.Effects = DragDropEffects.None;

            }
            else
                drgevent.Effects = DragDropEffects.None;
        }

最好创建实现
Textbox
的自己的Textbox类。然后覆盖OnDrag事件并将
e.handled
设置为
false
或执行任何您想要的操作


使用不是为最初想要的行为而创建的事件有点脏。预览是在提交真正的DragDrop事件之前检查一些内容,并有一个很好的撤消选项。

+1谢谢,对我也有用。。。尽管如此,它会重置DragEnter事件中设置的效果。需要找到一些复杂的方法来处理这个问题。它是有效的,我通过设置文本框的text=files[0]使文本框的文本成为文件路径