Wpf: перетаскивание в текстовое поле - PullRequest
30 голосов
/ 26 ноября 2010

Я погуглил эту проблему, и люди ответили на похожие вопросы, но по какой-то причине я не могу заставить что-либо работать.Должно быть, я что-то здесь упустил ... Во всяком случае, когда я запускаю следующий код, обработчик TextBox_DragEnter никогда не вызывается.Однако, если я изменяю элемент TextBox в xaml на элемент 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)
        {

        }
    }
}

Заранее большое спасибо!

Эндрю

РЕДАКТИРОВАТЬ:

Просто чтобы уточнить, я хотел бы разрешить падение пользовательского объекта в текстовое поле.Затем в обработчике отбрасывания для текстового поля я хотел бы установить для текста текстового поля свойство в объекте, а затем для свойства IsReadOnly объекта TextBox установить значение false.У меня просто проблемы с включением перетаскивания для TextBox ...

Ответы [ 4 ]

53 голосов
/ 26 ноября 2010

Если вы добавите обработчик для PreviewDragOver, тогда установите e.Handled = true, он должен работать.

У меня работает в любом случае.

14 голосов
/ 18 апреля 2014

TextBox, кажется, уже имеет некоторую обработку по умолчанию для DragAndDrop.Если ваш объект данных является строкой, он просто работает.Другие типы не обрабатываются, и вы получаете эффект мыши Forbidden , а ваш обработчик Drop никогда не вызывается.

Кажется, что вы можете включить свою собственную обработку с e.Handled до true вPreviewDragOver обработчик событий.

Я не смог найти какие-либо подробности об этом в MSDN, но нашел http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF очень полезным.

6 голосов
/ 17 сентября 2014

Возможно, вы захотите обрабатывать PreviewDragEnter так же, как PreviewDragOver, или для первого пикселя по умолчанию будет использоваться запрещенная мышь.

В обработчике убедитесь, что DragEventArgs.Data - это тип, который вы хотите отбросить. Если это так, установите DragEventsArgs.Effects в DragDropEffects.Move или что-то еще в AllowedEffects. Если это не тот тип, который вы хотите удалить, установите значение DragDropEffects.None, которое отключает удаление.

XAML для MVVM Light:

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

Обработчик во 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;
        }
0 голосов
/ 07 июня 2018

Лучше создайте свой собственный класс Textbox, который реализует Textbox. Затем переопределите OnDrag-Events и установите e.handled на false или делайте что хотите.

Немного грязно использовать события, которые не созданы для исходного требуемого поведения. Предварительный просмотр состоит в том, чтобы проверить некоторые вещи и иметь хороший вариант отмены перед совершением реальных событий DragDrop.

...