2010-11-26 4 views
22

J'ai googlé ce problème, et les gens ont répondu à des questions similaires, mais pour une raison quelconque, je ne peux rien pour travailler. Je dois avoir manqué quelque chose ici ... En tout cas, quand je cours le code suivant, le gestionnaire de TextBox_DragEnter n'est jamais appelé. Cependant, si je change l'élément TextBox dans le xaml en un élément TextBlock, il est appelé. Est-il possible d'obtenir le même comportement à partir d'un élément TextBox? Le code suivant isole complètement le problème ...WPF: glisser-déposer pour une zone de texte

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

     } 
    } 
} 

Un grand merci à l'avance!

Andrew

EDIT:

Juste pour clarifier les choses, je voudrais permettre à laisser tomber un objet personnalisé dans une zone de texte. Dans le gestionnaire d'abandon pour la zone de texte, je voudrais alors définir le texte de la zone de texte à une propriété dans l'objet, puis définissez la propriété IsReadOnly de la zone de texte sur false. J'ai juste quelques difficultés à activer le glisser-déposer pour le TextBox ...

Répondre

40

Si vous ajoutez un gestionnaire pour PreviewDragOver, alors définissez e.Handled = true cela devrait fonctionner.

Fonctionne pour moi dans tous les cas.

+0

Merci Liz! Cela fonctionne très bien! – Andrew

+0

+1 Merci, a travaillé pour moi aussi ... Bien, alors il réinitialise le jeu d'effets dans l'événement DragEnter. Besoin de trouver un moyen sophistiqué de gérer cela. – Indigo

12

TextBox semble avoir déjà une gestion par défaut pour DragAndDrop. Si votre objet de données est une chaîne, cela fonctionne simplement. Les autres types ne sont pas gérés et vous obtenez l'effet de souris Interdit et votre gestionnaire de Drop n'est jamais appelé.

Il semble que vous puissiez activer votre propre gestion avec e.Handled à true dans un gestionnaire d'événements PreviewDragOver.

Je n'ai pas trouvé de détails à ce sujet à MSDN, mais trouvé http://www.codeproject.com/Articles/42696/Textbox-Drag-Drop-in-WPF très utile.

4

Vous pouvez également gérer PreviewDragEnter de la même manière que PreviewDragOver ou la souris interdite par défaut sur le premier pixel.

Dans le gestionnaire assurez-vous que DragEventArgs.Data est le type que vous souhaitez supprimer. Si c'est le cas, définissez DragEventsArgs.Effects sur DragDropEffects.Move ou autre chose dans AllowedEffects. Si ce n'est pas le type que vous voulez supprimer, définissez DragDropEffects.None, ce qui désactive la suppression.

XAML pour MVVM Lumière:

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

cela fonctionne, et je fais que le texte de la zone de texte devient le chemin du fichier en définissant TextBox's text = files [0] –

Questions connexes