Событие WPF C# PreviewDrop/Drop не запускается (с помощью dragadorner)

Я предполагаю, что предпросмотр / удаление событий происходит, когда он обнаруживает цель перетаскивания с элементом в качестве цели перетаскивания. В этом случае моя цель перетаскивания - это текстовое поле, а цель перетаскивания - метка. Оба они динамически создаются из БД. Я использую DragAdorner для клонирования перетаскиваемого элемента, до реализации DragAdorner мой DnD работает хорошо, но после того, как я использую dragadorner, он не будет работать. И я замечаю, что мое событие предварительного просмотра не запускается, когда я пытаюсь отладить.

Вот мои коды:

 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;

И файл класса 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;

}

Я видел http://www.adorkable.us/books/wpf_control_development.pdf (стр. 103), но это слишком сложно для меня, так как я новичок.

Это из-за моего события GiveFeedBack, которое конфликтует с другими событиями?

2 ответа

Решение

Так как ваш DragAdorner всегда находится под вашим курсором, это будет объект, получающий падение. Если вы установите IsHitTestVisible = false; в конструкторе для Adorner, это должно исправить это.

Даже если вы не установили AllowDrop на Adorner, поскольку он находится под курсором, он будет перехватывать попытку сброса. Но так как он не принимает сброс, он просто отменит его.

Обновить

Другая проблема заключается в том, что вы устанавливаете разрешенные эффекты в вашей операции перетаскивания на DragDropEffects.Copy, но в DragOver а также Drop обработчики, вы пытаетесь сделать DragDropEffects.Move, Это не будет работать, так как это не та же самая операция. Они должны совпадать. Если вы хотите включить обе операции при перетаскивании, вы можете указать обе с помощью побитового или:

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

Обновление 2

Если вы хотите отбросить что-либо кроме string на TextBox, вы должны использовать PreviewDrop а также PreviewDragOver События. В противном случае TextBoxОбработка по умолчанию игнорирует все остальное. Так это будет выглядеть так:

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

Попробуйте установить цвет фона для вашей этикетки и посмотрите, будет ли он работать правильно.

Другие вопросы по тегам