2013-08-12 8 views
5

Zakładam, że zdarzenia previewdrop/drop były uruchamiane, gdy wykryły cel przeciągania z elementem jako celem upuszczenia. W tym przypadku moim celem upuszczania jest pole tekstowe, a moim celem przeciągania jest etykieta. Oba są dynamicznie tworzone z DB. Używam DragAdornera do klonowania elementu, który przeciągam, przed implementacją DragAdornera, mój DnD działa dobrze, ale po użyciu dragadornera to nie zadziała. I zauważam, że moje zdarzenie podglądu nie uruchamia się, gdy próbuję debugować.WPF C# PreviewDrop/Drop event not fired (With dragadorner)

Oto moje kody:

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; 

a plik klasy adorner:

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; 

}

widziałem http://www.adorkable.us/books/wpf_control_development.pdf (strona 103), ale jego zbyt skomplikowane dla mnie, jako Jestem nowicjuszem.

To z powodu mojego zdarzenia GiveFeedBack, które jest w konflikcie z innymi zdarzeniami?

Odpowiedz

3

Ponieważ Twój DragAdorner jest zawsze pod kursorem, będzie to obiekt odbierający kroplę. Jeśli ustawisz IsHitTestVisible = false; w konstruktorze dla Adorner, powinno to naprawić.

Mimo że nie ustawiono AllowDrop na Adorner, ponieważ znajduje się on pod kursorem, przechwyci próbę upuszczenia. Ale ponieważ nie akceptuje upuszczania, po prostu go anuluje.

Aktualizacja

Innym problemem jest to, że ustawiasz dozwolonych zmiany w operacji przeciągania do DragDropEffects.Copy, ale w DragOver i Drop koparki, starasz się zrobić DragDropEffects.Move. To nie zadziała, ponieważ są to takie same operacje, co . Te muszą pasować. Jeśli chcesz włączyć obie operacje na ulicy, można określić zarówno z bitowym OR:

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

Aktualizacja 2

Jeśli chcesz usunąć coś innego niż string wychodzą na TextBox, masz używać zdarzeń PreviewDrop i PreviewDragOver. W przeciwnym razie domyślna obsługa TextBox zignoruje cokolwiek innego. Tak więc wyglądałoby to tak:

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

cześć, ustawiłem IsHitTestVisible = false. nadal nie spadnie. Przepraszam, ale nie bardzo rozumiem twoje drugie zdanie na temat próby upuszczenia i stuffów. – user2376998

+0

Zasadniczo, WPF wykona test trafienia w miejscu kursora i spróbuje upuścić na najwyższym elemencie. Jeśli ten element nie zaakceptuje kropli, operacja zostanie anulowana. Dlatego ważne jest wyłączanie testowania trafień na twoim "Adornerze" ('Adorner's są zawsze na wierzchu). –

+0

Mam wyłączone hittest, nie działa, czy są jakieś inne problemy? – user2376998

0

Spróbuj ustawić kolor tła etykiety i sprawdź, czy będzie działał prawidłowo.

+0

na przezroczysty? nie działa. – user2376998

+0

brak przezroczystego, tylko kolor – mat

+0

nie działa zbyt/ – user2376998