使用坐标将对象拖放到 Canvas 上

Drag and Drop Object onto Canvas with coordinates

我设法将项目从我的 ListView 拖放到 canvas 上并在其上显示图像。我用这个问题作为模板: https://social.msdn.microsoft.com/Forums/en-US/cef5c42c-87a0-4e19-afc8-935284607488/drag-and-drop-controls-issue-from-listbox-into-canvas-wpf?forum=wpf

我还在该线程中添加了建议,以便项目在我放置它的地方呈现。这些是我的 "Drawing Plate"(canvas)和 ListView 的代码:

Canvas:

public partial class DrawingPlateUC : UserControl
{
    IMessenger messenger = Messenger.Instance;

    public DrawingPlateUC()
    {
        InitializeComponent();
    }

    void Canvas_Drop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent("MyFormat"))
        {
            var module = e.Data.GetData("MyFormat") as Module;
            Canvas CanvasView = sender as Canvas;

            Image image = new Image();
            image.Source = module.ModuleImage;

            CanvasView.Children.Add(image);
        }
    }

    private void Canvas_DragOver(object sender, DragEventArgs e)
    {
        // write down this point to a private member
        Point enterPoint = e.GetPosition(this.moduleCanvas);

        messenger.Send<Point>(enterPoint, MessengerTopics.MousePoint);
    }

    void Canvas_DragEnter(object sender, DragEventArgs e)
    {
        if (!(e.Data.GetDataPresent("contact")) || (sender == e.Source))
        {
            e.Effects = DragDropEffects.Copy;
        }
    }
}

列表视图:

public partial class ItemListViewUC : UserControl
{

    IMessenger messenger = Messenger.Instance;

    Point startPoint;
    Point enterPoint;

    public ItemListViewUC()
    {
        messenger.Register<Point>(this, MessengerTopics.MousePoint, GetEnterPoint);

        InitializeComponent();
    }

    private void GetEnterPoint(Point point)
    {
        enterPoint = point;
    }

    void StackPanel_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        startPoint = e.GetPosition(null);
    }

    void StackPanel_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        Point mousPos = e.GetPosition(null);
        Vector diff = startPoint - mousPos;

        if ((e.LeftButton == MouseButtonState.Pressed) && (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance) && (Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
        {
            ListView listView = sender as ListView;
            ListViewItem listViewItem = FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);
            if (listViewItem == null) { return; }
            var contact = (Module)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);
            DataObject dataObject = new DataObject("MyFormat", contact);
            try
            {
                DragDrop.DoDragDrop(listViewItem, dataObject, DragDropEffects.Copy);
            }
            catch { }
            // Set the Margin property to place the drag item on the canvas.
            listViewItem.Margin = new Thickness(enterPoint.X, enterPoint.Y, 0, 0);
        }
    }

    static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject
    {
        do
        {
            if (current is T)
            {
                return (T)current;
            }
            current = VisualTreeHelper.GetParent(current);
        }
        while (current != null);

        return null;
    }
}

这里应该是在我放下它的地方绘制图像:

listViewItem.Margin = new Thickness(enterPoint.X, enterPoint.Y, 0, 0);

但它只渲染在canvas的左上角,坐标0, 0。这是我放下的所有物品,它们覆盖在那个位置。我已经检查过坐标,它们不是0、0,而是我放下物品时鼠标所在的坐标。

这是我的 Window:

当你放下一个项目时,你没有为图像设置任何坐标:

void Canvas_Drop(object sender, DragEventArgs e)
{
    if (e.Data.GetDataPresent("MyFormat"))
    {
        var module = e.Data.GetData("MyFormat") as Module;
        Canvas CanvasView = sender as Canvas;

        Image image = new Image();
        image.Source = module.ModuleImage;
        image.SetValue(Canvas.LeftProperty, _enterPoint.X);
        image.SetValue(Canvas.TopProperty, _enterPoint.Y);

        CanvasView.Children.Add(image);
    }
}

private Point _enterPoint;
private void Canvas_DragOver(object sender, DragEventArgs e)
{
    _enterPoint = e.GetPosition(this.moduleCanvas);

    messenger.Send<Point>(_enterPoint, MessengerTopics.MousePoint);
}