Wpf:拖放到文本框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4281857/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 22:20:50  来源:igfitidea点击:

Wpf: Drag And Drop To A Textbox

wpftextboxdrag-and-drop

提问by Andrew

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. However, if I change the TextBox element in the xaml to a TextBlock element, it is called. Is there any way to get the same behavior from a TextBox element? The following code completely isolates the problem...

我在谷歌上搜索了这个问题,人们已经回答了类似的问题,但由于某种原因,我无法解决任何问题。我一定在这里错过了一些东西......无论如何,当我运行以下代码时,永远不会调用 TextBox_DragEnter 处理程序。但是,如果我将 xaml 中的 TextBox 元素更改为 TextBlock 元素,则会调用它。有没有办法从 TextBox 元素获得相同的行为?以下代码完全隔离了问题...

MainWindow.xaml:

主窗口.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:

主窗口.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. I'm just having some trouble enabling drag and drop for the TextBox...

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

回答by Liz

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.

在任何情况下都对我有用。

回答by trapicki

TextBoxseems to have already some default handling for DragAndDrop. If your data object is a String, it simply works. Other types are not handled and you get the Forbiddenmouse effect and your Drop handler is never called.

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

It seems like you can enable your own handling with e.Handledto truein a PreviewDragOverevent handler.

好像你可以使自己的操作e.Handled,以truePreviewDragOver事件处理程序。

I could not find any details about that at MSDN, but found http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPFvery helpfull.

我在 MSDN 上找不到关于它的任何详细信息,但发现http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF非常有帮助。

回答by haps

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,否则它将默认为第一个像素上的禁止鼠标。

In the handler make sure the DragEventArgs.Data is the type you want to drop. If it is, set DragEventsArgs.Effects to DragDropEffects.Move or something else in AllowedEffects. If it isn't the type you want to drop, set to DragDropEffects.None which disables dropping.

在处理程序中,确保 DragEventArgs.Data 是您要删除的类型。如果是,请将 DragEventsArgs.Effects 设置为 DragDropEffects.Move 或 AllowedEffects 中的其他内容。如果它不是您要放置的类型,请设置为 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;
        }

回答by Tost

Better create your own Textbox class that implements Textbox. Then override the OnDrag-Events and set e.handledto falseor do whatever you want.

最好创建自己的 Textbox 类,该类实现Textbox. 然后覆盖 OnDrag-Events 并设置e.handledfalse或执行您想要的任何操作。

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 之前检查一些东西并有一个很好的撤消选项。