使用拖动装饰器进行拖放

use*_*998 5 c# wpf drag-and-drop adorner

我使用拖动装饰器来克隆标签的图像(拖动目标),但现在我无法将标签放入文本框中,

这是我使用的代码(你可能会看到那里的previewdragover,我在previewdragover中写了e.Handled = true,但没有帮助)我还将tbox.AllowDrop设置为true:

文本框 :

  tbox.PreviewDrop += new DragEventHandler(tbox_PreviewDrop);
  tbox.PreviewDragOver += new DragEventHandler(tbox_PreviewDragOver);
Run Code Online (Sandbox Code Playgroud)

文本框的处理程序:

   protected 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.Handled = true;
    }
Run Code Online (Sandbox Code Playgroud)

标签(拖动目标):

             Label lbl = new Label();
             lbl.Content = s;
             lbl.Width = Double.NaN;
             lbl.Height = 40;
             lbl.FontSize = 19;
             lbl.MouseDown += new MouseButtonEventHandler(lbl_MouseDown);
             lbl.MouseMove += new MouseEventHandler(lbl_MouseMove);
             lbl.GiveFeedback += new GiveFeedbackEventHandler(lbl_GiveFeedback);
             lbl.MouseUp += new MouseButtonEventHandler(lbl_MouseUp); 
             wrapPanel2.Children.Add(lbl);
Run Code Online (Sandbox Code Playgroud)

标签处理程序:

        private void lbl_MouseUp(object sender, MouseButtonEventArgs e)
    {
        Mouse.OverrideCursor = Cursors.Arrow;
    }

    private void lbl_MouseDown(object sender, MouseButtonEventArgs e)
    {
        startPoint = e.GetPosition(this);

    }

    private void lbl_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {


            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);
        }
    }

    [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;
Run Code Online (Sandbox Code Playgroud)

现在我可以用光标跟随的标签拖动标签,但无法将它们放入任何文本框中。

- - -编辑 - - - - - -

我为文本框放置了一个拖动器,如下所示:

       private void tbox_PreviewDragEnter(object sender, DragEventArgs e)
    {
        if (sender == e.Source)
        {
            e.Effects = DragDropEffects.None;
        }

    }
Run Code Online (Sandbox Code Playgroud)

仍然没有工作。

我将在这里添加我使用过的 DragAdorner.cs (我从一些中文网站获得它):

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;
Run Code Online (Sandbox Code Playgroud)

She*_*dan 0

您的代码与我的工作示例有些不同,但我认为我可以看到您的问题。在我的代码中,我有一个名为 的方法UpdateDragDropEffects。此方法接受DragEventArgs名为name 类型的对象e,并e.Effects根据属性的值e.AllowedEffects以及我是否有ICommand要调用的有效实例以及数据是否属于预期类型等来更新属性。

该方法调用(以及DragEventArgs从中传递的对象)两个典型的拖放方法;DragTargetPreviewDrop(处理PreviewDrop事件)和AdornedUIElementPreviewDragOver(处理PreviewDragOver事件)。设置对象e.Effects的属性DragEventArgs告诉系统当前的拖动操作是否有效以及是否应该继续...不设置它,或者将其设置为DragDropEffects.None将具有不显示任何有效放置目标的效果。

MSDN 上的拖放概述页面提供的代码示例也应该对您有所帮助。本Enabling an Element to be a Drop Target节有示例代码,显示了我所描述的内容。

您还可能遇到其他问题,但如果这对您没有帮助,请回来更新。

  • 另一件事......是你的整个“DragAdorner”类吗?它看起来绝对“一点也不像”我的。“VisualChildrenCount”属性、“MeasureOverride”、“ArrangeOverride”和“GetVisualChild”方法的重写在哪里?您可以在这篇[WPF:拖放装饰器](http://codeblitz.wordpress.com/2009/06/17/wpf-drag-drop-adorner/)文章中找到更好的示例。这篇 [WPF 中的拖放 - 第 II 部分](http://www.codeproject.com/Articles/43702/Drag-and-Drop-in-WPF-Part-II) 文章也应该对您有所帮助(尤其是对于“e .效果`)。 (2认同)