2013-08-12 21 views
5

Ich nehme an, dass Previewdrop/Drop-Ereignisse ausgelöst, wenn es ein Ziehziel mit einem Element als Drop-Ziel erkennen. In diesem Fall ist mein Ablageziel ein Textfeld und mein Ziehziel ist ein Etikett. Beide werden dynamisch aus der DB erstellt. Ich benutze DragAdorner, um das Element, das ich ziehe, zu klonen, bevor ich den DragAdorner implementiere, mein DnD funktioniert gut, aber nachdem ich den Dragadorner benutzt habe, wird es nicht funktionieren. Und ich merke, dass mein Prekiddrop Event nicht ausgelöst wird, wenn ich versuche zu debuggen.WPF C# PreviewDrop/Drop-Ereignis nicht ausgelöst (Mit Dragadorner)

Hier sind meine Codes:

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; 

Und die adorner Klassendatei:

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; 

}

I http://www.adorkable.us/books/wpf_control_development.pdf (Seite 103), aber seine viel zu kompliziert für mich, wie ich gesehen Bin ein Neuling.

Es ist wegen meiner GiveFeedBack-Ereignis, das im Konflikt mit anderen Ereignissen ist?

Antwort

3

Da Ihr DragAdorner immer unter Ihrem Cursor ist, wird es das Objekt sein, das den Tropfen erhält. Wenn Sie IsHitTestVisible = false; im Konstruktor für die Adorner festlegen, sollte dies behoben werden.

Auch wenn Sie AllowDrop nicht auf Adorner eingestellt haben, wird der Drop-Versuch abgefangen, da er sich unter dem Cursor befindet. Aber da es keinen Drop akzeptiert, wird es einfach abgebrochen.

aktualisieren

Das andere Problem ist, dass Sie die zulässigen Auswirkungen in Ihrer Drag-Operation zu DragDropEffects.Copy, aber in den DragOver und Drop Handler setzen, Sie versuchen, eine DragDropEffects.Move zu tun. Dies wird nicht funktionieren, da diese nicht die gleiche Operation sind. Diese müssen übereinstimmen. Wenn Sie beiden Operationen auf Drag aktivieren mögen, können Sie beide mit einem bitweise angeben oder:

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

Update 2

Wenn Sie etwas wollen, dass andere als ein string auf ein TextBox fallen zu lassen, haben Sie die PreviewDrop und PreviewDragOver Ereignisse zu verwenden. Ansonsten ignoriert die Standardbehandlung von TextBox alles andere. So würde es so aussehen:

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

hi, ich habe IsHitTestVisible = false gesetzt. es wird immer noch nicht fallen. Sorry, aber ich verstehe nicht ganz Ihren zweiten Satz auf Drop-Versuch und stopft – user2376998

+0

Grundsätzlich wird WPF einen Treffer-Test an der Cursor-Position und versuchen, auf das oberste Element fallen. Wenn dieses Element keine Tropfen akzeptiert, wird die Operation abgebrochen. Deshalb ist es wichtig, Hit-Tests auf deinem 'Adorner' zu deaktivieren (' Adorner's sind immer oben). –

+0

Ich habe Hittest deaktiviert, funktioniert nicht, gibt es noch andere Probleme? – user2376998

0

Versuchen Sie, die Hintergrundfarbe für Ihr Etikett einzustellen und zu überprüfen, ob es richtig funktioniert.

+0

zu transparent? funktioniert nicht. – user2376998

+0

nein transparent, nur eine Farbe – mat

+0

funktioniert auch nicht/ – user2376998