Question

I assume that previewdrop/drop events fired when it detect a drag target with an element as a drop target . In this case , my drop target is a textbox and my drag target is a label. Both of them are dynamically created from DB . I am using DragAdorner to clone the element that i am dragging , before implementing the DragAdorner , my DnD works well but after i use the dragadorner , it won't work . And i notice my previewdrop event is not firing when i try to debug .

Here are my 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;

And the adorner class file :

 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 seen http://www.adorkable.us/books/wpf_control_development.pdf ( page 103 ) but its way too complicated for me as i am a newbie .

It is because of my GiveFeedBack event that is in conflict with other events?

Was it helpful?

Solution

Since your DragAdorner is always under your cursor, it will be the object receiving the drop. If you set IsHitTestVisible = false; in the constructor for the Adorner, it should fix this.

Even though you haven't set AllowDrop on the Adorner, since it is under the cursor, it will intercept the drop attempt. But since it doesn't accept drop, it will just cancel it.

Update

The other issue is that you are setting the allowed effects in your drag operation to DragDropEffects.Copy, but in the DragOver and Drop handlers, you're trying to do a DragDropEffects.Move. This won't work, as those are not the same operation. These must match. If you want to enable both operations on drag, you can specify both with a bitwise or:

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

Update 2

If you want to drop anything other than a string onto a TextBox, you have to use the PreviewDrop and PreviewDragOver events. Otherwise, the TextBox's default handling will ignore anything else. So it would look like this:

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

OTHER TIPS

Try setting background color for your label and see if it will work properly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top