2013-08-12 18 views
5

Presumo che gli eventi di anteprimadrop/rilascio attivati ​​quando rilevano un target di trascinamento con un elemento come destinazione di rilascio. In questo caso, il mio drop target è una casella di testo e il mio target di trascinamento è un'etichetta. Entrambi sono creati dinamicamente dal DB. Sto usando DragAdorner per clonare l'elemento che sto trascinando, prima di implementare il DragAdorner, il mio DnD funziona bene ma dopo aver usato il dragadorner, non funzionerà. E noto che il mio evento previewdrop non si attiva quando provo a eseguire il debug.WPF C# PreviewDrop/Drop evento non attivato (con dragadorner)

Qui sono i miei codici:

tbox.Drop += new DragEventHandler(tbox_PreviewDrop); // text box , Drop Target 
tbox.DragOver += new DragEventHandler(tbox_DragOver); 

Label lbl = new Label(); // Label , Drag Target 
      lbl.Content = s; 
      lbl.Width = Double.NaN; 
      lbl.Height = 40; 
      lbl.FontSize = 19; 
      lbl.PreviewMouseDown += new MouseButtonEventHandler(lbl_MouseDown); 
      lbl.PreviewMouseMove += new MouseEventHandler(lbl_MouseMove); 
      lbl.PreviewGiveFeedback += new GiveFeedbackEventHandler(lbl_GiveFeedback); 


    private void lbl_MouseDown(object sender, MouseButtonEventArgs e) 
    { 
     startPoint = e.GetPosition(this); 
     // Mouse.OverrideCursor = Cursors.None; 

    } 

    private void lbl_MouseMove(object sender, MouseEventArgs e) 
    { 

     if (e.LeftButton == MouseButtonState.Pressed) 
     { 

      // Mouse.OverrideCursor = Cursors.None; 

      var source = sender as UIElement; 
      Label lbl = sender as Label; 
      Point current = e.GetPosition(this); 
      Vector diff = startPoint - current; 

      if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance || 
       Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) 
      { 

       adorner = new DragAdorner(lbl, e.GetPosition(lbl)); 
       AdornerLayer.GetAdornerLayer(lbl).Add(adorner); 

       var dragData = new DataObject(this); 
       DragDrop.DoDragDrop(source, dragData, DragDropEffects.Copy); 
       AdornerLayer.GetAdornerLayer(lbl).Remove(adorner); 

      } 
      startPoint = current; 
     } 
    } 

    private void lbl_GiveFeedback(object sender, GiveFeedbackEventArgs e) 
    { 
     if (adorner != null) 
     { 
      Label lbl = sender as Label; 
      var pos = lbl.PointFromScreen(GetMousePosition()); 
      adorner.UpdatePosition(pos); 
      e.Handled = true; 

     } 
    } 



private void tbox_PreviewDrop(object sender, DragEventArgs e) 
     { 

      (sender as TextBox).Text = string.Empty; // Empty the textbox from previous answer. 
      (sender as TextBox).Background = Brushes.White; 
      e.Effects = DragDropEffects.Move; 
      e.Handled = true; 

     } 

     private void tbox_DragOver(object sender, DragEventArgs e) 
     { 
      e.Handled = true; 
      e.Effects = DragDropEffects.Move; 

     } 
    [DllImport("user32.dll")] 
    [return: MarshalAs(UnmanagedType.Bool)] 
    internal static extern bool GetCursorPos(ref Win32Point pt); 

    [StructLayout(LayoutKind.Sequential)] 
    internal struct Win32Point 
    { 
     public Int32 X; 
     public Int32 Y; 
    }; 

    public static Point GetMousePosition() 
    { 
     Win32Point w32Mouse = new Win32Point(); 
     GetCursorPos(ref w32Mouse); 
     return new Point(w32Mouse.X, w32Mouse.Y); 
    } 

    private Point startPoint; 
    private DragAdorner adorner; 

E il file di classe strumento decorativo:

public class DragAdorner : Adorner { 

public DragAdorner(UIElement adornedElement, Point offset) 

    : base(adornedElement) { 

    this.offset = offset; 

    vbrush = new VisualBrush(AdornedElement); 
    //vbrush.Opacity = .7; 

} 



public void UpdatePosition(Point location) { 

    this.location = location; 

    this.InvalidateVisual(); 

} 



protected override void OnRender(DrawingContext dc) { 

    var p = location; 

    p.Offset(-offset.X, -offset.Y); 

    dc.DrawRectangle(vbrush, null, new Rect(p, this.RenderSize)); 

} 



private Brush vbrush; 

private Point location; 

private Point offset; 

}

ho visto http://www.adorkable.us/books/wpf_control_development.pdf (pagina 103), ma il suo modo troppo complicato per me, come ho sono un principiante.

È a causa del mio evento GiveFeedBack che è in conflitto con altri eventi?

risposta

3

Dato che il tuo DragAdorner è sempre sotto il tuo cursore, sarà l'oggetto che riceve il drop. Se si imposta IsHitTestVisible = false; nel costruttore per lo Adorner, è necessario correggerlo.

Anche se non è stato impostato AllowDrop su Adorner, poiché è sotto il cursore, intercetterà il tentativo di rilascio. Ma dal momento che non accetta la cancellazione, lo annulla semplicemente.

Aggiornamento

L'altra questione è che si sta impostando gli effetti consentiti nella vostra operazione di trascinamento per DragDropEffects.Copy, ma nelle DragOver e Drop gestori, si sta cercando di fare un DragDropEffects.Move. Ciò non funzionerà, poiché quelli sono non la stessa operazione. Questi devono corrispondere. Se si desidera attivare entrambe le operazioni su di trascinamento, è possibile specificare sia con un bit per bit o:

DragDrop.DoDragDrop(source, dragData, DragDropEffects.Copy | DragDropEffects.Move); 

Update 2

Se si vuole far cadere qualcosa di diverso da un string su un TextBox, avete per utilizzare gli eventi PreviewDrop e PreviewDragOver. In caso contrario, la gestione predefinita di ignorerà qualsiasi altra cosa. Quindi sarebbe simile a questo:

tbox.PreviewDrop += new DragEventHandler(tbox_PreviewDrop); 
tbox.PreviewDragOver += new DragEventHandler(tbox_DragOver); 
+0

ciao, ho impostato IsHitTestVisible = false. ancora non cadrà. Scusate ma non capisco la vostra seconda frase sul tentativo di caduta e gli animali – user2376998

+0

Fondamentalmente, WPF eseguirà un hit test nella posizione del cursore e cercherà di rilasciare l'elemento più in alto. Se quell'elemento non accetta gocce, l'operazione verrà annullata. Questo è il motivo per cui disabilitare il test di successo su 'Adorner' è importante (' Adorner's è sempre in primo piano). –

+0

ho disabilitato il hittest, non funziona, ci sono altri problemi? – user2376998

0

Provare a impostare il colore di sfondo per l'etichetta e vedere se funzionerà correttamente.

+0

trasparente? non funziona – user2376998

+0

non trasparente, solo un colore – mat

+0

non funziona troppo/ – user2376998

Problemi correlati