Ответ 1
Если вы добавите обработчик для PreviewDragOver, установите e.Handled = true, он должен работать.
Работает для меня в любом случае.
Я столкнулся с этой проблемой, и люди ответили на подобные вопросы, но по какой-то причине я не могу заставить ничего работать. Я, должно быть, что-то пропустил... Во всяком случае, когда я запускаю следующий код, обработчик 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)
{
}
}
}
Большое спасибо заранее!
Эндрю
EDIT:
Чтобы уточнить, я хотел бы разрешить отбрасывать пользовательский объект в текстовое поле. В обработчике Drop для текстового поля я хотел бы затем установить текст текстового поля в свойство объекта, а затем установить для свойства IsReadOnly TextBox значение false. У меня просто проблемы с перетаскиванием для TextBox...
Если вы добавите обработчик для PreviewDragOver, установите e.Handled = true, он должен работать.
Работает для меня в любом случае.
TextBox
Кажется, что уже некоторая обработка по умолчанию для DragAndDrop. Если ваш объект данных является строкой, он просто работает. Другие типы не обрабатываются, и вы получаете эффект Forbidden mouse, и обработчик Drop никогда не вызывается.
Кажется, вы можете включить собственную обработку с e.Handled
до true
в обработчике события PreviewDragOver
.
Я не мог найти никаких подробностей об этом в MSDN, но нашел http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF очень полезным.
Вы также можете обрабатывать 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;
}