2010-11-26 22 views
22

He buscado este problema en Google y la gente ha respondido preguntas similares, pero por alguna razón no puedo hacer que nada funcione. Debo haber perdido algo aquí ... En cualquier caso, cuando ejecuto el siguiente código, nunca se llama al controlador TextBox_DragEnter. Sin embargo, si cambio el elemento TextBox en el xaml a un elemento TextBlock, se llama. ¿Hay alguna forma de obtener el mismo comportamiento de un elemento TextBox? El siguiente código aísla por completo el problema ...Wpf: Arrastrar y soltar a un cuadro de texto

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

     } 
    } 
} 

Muchas gracias de antemano!

Andrew

EDIT:

Solo para aclarar, me gustaría que permita dejar caer un objeto personalizado en un cuadro de texto. En el controlador de soltar para el cuadro de texto, me gustaría establecer el texto del cuadro de texto en una propiedad en el objeto, y luego establecer la propiedad IsReadOnly del TextBox en falso. Solo estoy teniendo problemas para habilitar la función de arrastrar y soltar para el TextBox ...

Respuesta

40

Si agrega un controlador para PreviewDragOver, entonces configure e.Handled = true debería funcionar.

Funciona para mí en cualquier caso.

+0

Gracias Liz! Eso funciona genial! – Andrew

+0

+1 Gracias, funcionó para mí también ... Aunque, restablece los efectos establecidos en el evento DragEnter. Necesita encontrar una forma sofisticada de manejar esto. – Indigo

12

TextBox parece que ya tiene un manejo predeterminado para DragAndDrop. Si su objeto de datos es una Cadena, simplemente funciona. No se manejan otros tipos y obtienes el Forbidden Forbidden efecto del mouse y nunca se llama a tu controlador Drop.

Parece que puede activar su propio manejo con e.Handled a true en un manejador PreviewDragOver evento.

No he podido encontrar ningún detalle al respecto en MSDN, pero ha encontrado http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF muy útil.

4

Es posible que también desee manejar PreviewDragEnter de la misma manera que PreviewDragOver o de forma predeterminada será el Mouse prohibido en el primer píxel.

En el controlador, asegúrese de que DragEventArgs.Data es del tipo que desea descartar. Si es así, configure DragEventsArgs.Effects para DragDropEffects.Move u otra cosa en AllowedEffects. Si no es el tipo que desea descartar, configúrelo en DragDropEffects.None, que desactiva la posibilidad de descartar.

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

Handler en el modelo de vista:

 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

funciona, y hago que el texto del cuadro de texto se convierta en la ruta del archivo estableciendo TextBox's text = files [0] –