简体   繁体   English

Wpf:拖放到文本框

[英]Wpf: Drag And Drop To A Textbox

I've googled this problem, and people have answered similar questions, but for some reason I can't get anything to work. 我搜索了这个问题,人们已经回答了类似的问题,但由于某种原因,我无法得到任何工作。 I must have missed something here... At any rate, when I run the following code, the TextBox_DragEnter handler is never called. 我一定在这里遗漏了一些东西......无论如何,当我运行以下代码时,永远不会调用TextBox_DragEnter处理程序。 However, if I change the TextBox element in the xaml to a TextBlock element, it is called. 但是,如果我将xaml中的T​​extBox元素更改为TextBlock元素,则会调用它。 Is there any way to get the same behavior from a TextBox element? 有没有办法从TextBox元素获得相同的行为? The following code completely isolates the problem... 以下代码完全隔离了问题......

MainWindow.xaml: 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: 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)
        {

        }
    }
}

Many thanks in advance! 提前谢谢了!

Andrew 安德鲁

EDIT: 编辑:

Just to clarify, I would like to allow dropping a custom object into a textbox. 为了澄清,我想允许将自定义对象放入文本框中。 In the Drop handler for the textbox, I would then like to set the text of the textbox to a property in the object, and then set the IsReadOnly property of the TextBox to false. 在文本框的Drop处理程序中,我想将文本框的文本设置为对象中的属性,然后将TextBox的IsReadOnly属性设置为false。 I'm just having some trouble enabling drag and drop for the TextBox... 我只是在为TextBox拖放时遇到一些麻烦......

If you add a handler for PreviewDragOver, then set e.Handled = true it should work. 如果为PreviewDragOver添加处理程序,则设置e.Handled = true它应该有效。

Works for me in any case. 无论如何都适合我。

TextBox seems to have already some default handling for DragAndDrop. TextBox似乎已经为DragAndDrop进行了一些默认处理。 If your data object is a String, it simply works. 如果您的数据对象是String,它就可以正常工作。 Other types are not handled and you get the Forbidden mouse effect and your Drop handler is never called. 其他类型未处理,您将获得Forbidden鼠标效果,并且永远不会调用Drop处理程序。

It seems like you can enable your own handling with e.Handled to true in a PreviewDragOver event handler. 好像你可以让自己的处理与e.HandledtruePreviewDragOver事件处理程序。

I could not find any details about that at MSDN, but found http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF very helpfull. 我在MSDN上找不到任何有关它的细节,但发现http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF非常有帮助。

You may also want to handle PreviewDragEnter the same way as PreviewDragOver or it will default to the Forbidden Mouse on the first pixel. 您可能还希望以与PreviewDragOver相同的方式处理PreviewDragEnter,或者它将默认为第一个像素上的Forbidden Mouse。

In the handler make sure the DragEventArgs.Data is the type you want to drop. 在处理程序中,确保DragEventArgs.Data是要删除的类型。 If it is, set DragEventsArgs.Effects to DragDropEffects.Move or something else in AllowedEffects. 如果是,请将DragEventsArgs.Effects设置为DragDropEffects.Move或AllowedEffects中的其他内容。 If it isn't the type you want to drop, set to DragDropEffects.None which disables dropping. 如果它不是您要删除的类型,请设置为DragDropEffects.None,以禁用删除。

XAML for MVVM Light: 适用于MVVM Light的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>

Handler in ViewModel: ViewModel中的处理程序:

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

Better create your own Textbox class that implements Textbox . 更好地创建自己的Textbox类来实现Textbox Then override the OnDrag-Events and set e.handled to false or do whatever you want. 然后覆盖OnDrag-Events并将e.handled设置为false或执行任何操作。

It's a little dirty to use events that are not made for the original wanted behavior. 使用不是原始通缉行为的事件会有点脏。 Preview is to check some stuff and have a good Undo option before committing the real DragDrop-Events. 在提交真正的DragDrop-Events之前,预览是检查一些东西并有一个很好的撤消选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM