C# 在 Canvas 中拖放图像

标签 c# wpf canvas drag-and-drop draggable

我尝试用 Google 搜索如何在 Canvas 上为 UIElements 进行拖放,但找不到我要找的任何东西。

我有一个带有窗口的 C# WPF 应用程序。在窗口内,我有一个 Canvas ,我可以在其中添加图像。 我想要的是能够拖放图像,同时保持在 Canvas 的边界内。 我也希望它在代码中,而不是在 xaml 中。

我在将图像添加/更新到 Canvas 的函数中得到了这个。 TODO 应该替换为拖放事件。

Image img = ImageList[i].Image;
img.Name = "Image" + i;

// TODO: Drag and Drop event for Image

// TODO: Check if Left and Top are within Canvas (minus width / height of Image) 

Canvas.SetLeft(img, Left); // Default Left when adding the image = 0
Canvas.SetTop(img, Top); // Default Top when adding the image = 0

MyCanvas.Children.Add(img);
OnPropertyChanged("MyCanvas");

PS:虽然这是以后的事,但如果有人有代码可以一次拖放多张图片作为额外奖励,我将不胜感激。

在此先感谢您的帮助。

最佳答案

使用以下代码解决了我的问题:

img.AllowDrop = true;
img.PreviewMouseLeftButtonDown += this.MouseLeftButtonDown;
img.PreviewMouseMove += this.MouseMove;
img.PreviewMouseLeftButtonUp += this.PreviewMouseLeftButtonUp;


private object movingObject;
private double firstXPos, firstYPos;
private void MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
    // In this event, we get the current mouse position on the control to use it in the MouseMove event.
    Image img = sender as Image;
    Canvas canvas = img.Parent as Canvas;

    firstXPos = e.GetPosition(img).X;
    firstYPos = e.GetPosition(img).Y;

    movingObject = sender;

    // Put the image currently being dragged on top of the others
    int top = Canvas.GetZIndex(img);
    foreach (Image child in canvas.Children)
        if (top < Canvas.GetZIndex(child))
            top = Canvas.GetZIndex(child);
    Canvas.SetZIndex(img, top + 1);
}
private void PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) {
    Image img = sender as Image;
    Canvas canvas = img.Parent as Canvas;

    movingObject = null;

    // Put the image currently being dragged on top of the others
    int top = Canvas.GetZIndex(img);
    foreach (Image child in canvas.Children)
        if (top > Canvas.GetZIndex(child))
            top = Canvas.GetZIndex(child);
    Canvas.SetZIndex(img, top + 1);
}
private void MouseMove(object sender, MouseEventArgs e) {
    if (e.LeftButton == MouseButtonState.Pressed && sender == movingObject) {
        Image img = sender as Image;
        Canvas canvas = img.Parent as Canvas;

        double newLeft = e.GetPosition(canvas).X - firstXPos - canvas.Margin.Left;
        // newLeft inside canvas right-border?
        if (newLeft > canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth)
            newLeft = canvas.Margin.Left + canvas.ActualWidth - img.ActualWidth;
        // newLeft inside canvas left-border?
        else if (newLeft < canvas.Margin.Left)
            newLeft = canvas.Margin.Left;
        img.SetValue(Canvas.LeftProperty, newLeft);

        double newTop = e.GetPosition(canvas).Y - firstYPos - canvas.Margin.Top;
        // newTop inside canvas bottom-border?
        if (newTop > canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight)
            newTop = canvas.Margin.Top + canvas.ActualHeight - img.ActualHeight;
        // newTop inside canvas top-border?
        else if (newTop < canvas.Margin.Top)
            newTop = canvas.Margin.Top;
        img.SetValue(Canvas.TopProperty, newTop);
    }
}

此代码允许我将图像拖放到 Canvas 中,而无需离开 Canvas 本身。

现在我只需要再做两件事:

  1. 修复了一个小错误,当我快速拖动鼠标时,鼠标会滑过图像。这种情况经常发生,即使我什至没有那么快地移动拖动图像。 Fixed by using the solution mentioned in my other question.
  2. 让它能够一次拖放多张图片,最好先选择多张,然后拖放整组图片,同时留在 Canvas 内。

将为此提出一个新问题。

关于C# 在 Canvas 中拖放图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21833168/

相关文章:

WPF 文本 block : How to evenly space displayed characters?

当项目源更改时,WPF ComboBox 会重置所选项目

java - 如何在不填充的情况下在位图上绘制圆圈?

c# - 有谁知道我在哪里可以找到基于文件的 c# 多路 B 树类?

c# - 获取 Internet Explorer 选项卡标题

c# - XAML Treeview,如何水平而不是垂直显示节点

javascript - Canvas 中的 SVG feComposite 过滤器实现

javascript - 大型 HTML5 Canvas 滚动性能提示

c# - 在.net中使用正则表达式匹配两个单词的正确模式

c# - Azure Function 不是无状态的