[英]C# Drag and Drop Image within Canvas
我尝试使用Google如何在Canvas上进行UIElement的拖放,但是找不到我想要的任何东西。
我有一个带有窗口的C#WPF应用程序。 在窗口内,我有一个画布,可以在其中添加图像。 我想要的是能够拖放图像,同时保持在画布的边界内。 我也希望这是在代码中,所以不在xaml中。
我在将图像添加/更新到画布的功能中得到了这一点。 拖放事件应替换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本身。
现在,我只需要能够做两件事:
为此将提出一个新的问题。
我做过一个使用您的代码块并将其拖放到画布上的项目,调查它是否存在差异,真的没有时间检查
private void pinCanvas_PreviewMouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
{
// Point pt = e.GetPosition(pinCanvas);
// Curosor.Text = String.Format("You are at ({0}in, {1}in) in window coordinates", (pt.X / (96 / 72)) * 1/72, (pt.Y / (96 / 72)) * 1/72);
}
bool captured = false;
double x_shape, x_canvas, y_shape, y_canvas;
UIElement source = null;
string elementName;
double elementHeight, elementWidth;
private void pinCanvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
setCanvasSize();
source = (UIElement)sender;
elementName = ((Label)source).Name;
switch (elementName)
{
case "pinTextBox" :
elementHeight = pinActualHeight;
elementWidth = pinActualWidth;
break;
case "serialTextBox" :
elementHeight = serialActualHeight;
elementWidth = serialActualWidth;
break;
case "batchTextBox" :
elementHeight = batchActualHeight;
elementWidth = batchActualWidth;
break;
}
Mouse.Capture(source);
captured = true;
x_shape = Canvas.GetLeft(source);
x_canvas = e.GetPosition(Maincanvas).X;
y_shape = Canvas.GetTop(source);
y_canvas = e.GetPosition(Maincanvas).Y;
}
private void pinCanvas_MouseMove(object sender, MouseEventArgs e)
{
if (captured)
{
double x = e.GetPosition(Maincanvas).X;
double y = e.GetPosition(Maincanvas).Y;
var xCond = Math.Round(appActivities.DIP2Inch(x_shape), 4).ToString();
var yCond = Math.Round(appActivities.DIP2Inch(y_shape), 4).ToString();
var name = ((Label)source).Name;
x_shape += x - x_canvas;
// if ((x_shape < Maincanvas.ActualWidth - elementWidth) && x_shape > 0)
// {
Canvas.SetLeft(source, x_shape);
switch (name)
{
case "pinTextBox" :
pinOffsetLeft.Text = xCond;
break;
case "serialTextBox" :
serialOffsetLeft.Text = xCond;
break;
case "batchTextBox" :
batchOffsetLeft.Text = xCond;
break;
}
// }
x_canvas = x;
y_shape += y - y_canvas;
// if (y_shape < Maincanvas.ActualHeight - elementHeight && y_shape > 0)
// {
Canvas.SetTop(source, y_shape);
switch (name)
{
case "pinTextBox":
pinOffsetTop.Text = yCond;
break;
case "serialTextBox":
serialOffsetTop.Text = yCond;
break;
case "batchTextBox":
batchOffsetTop.Text = yCond;
break;
}
// }
y_canvas = y;
}
}
private void pinCanvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
Mouse.Capture(null);
captured = false;
// MessageBox.Show((Canvas.GetTop(source)).ToString());
/* if (Canvas.GetTop(source) < 0)
{
Canvas.SetTop(source, 0);
}
if (Canvas.GetLeft(source) < 0)
{
Canvas.SetLeft(source, 0);
}
if (Canvas.GetLeft(source) > Maincanvas.ActualWidth - elementWidth)
{
// MessageBox.Show("Left Too Much " + (Canvas.GetLeft(source) * 1/96).ToString());
Canvas.SetLeft(source, Maincanvas.ActualWidth - elementWidth);
}
if (Canvas.GetTop(source) > Maincanvas.ActualHeight - elementHeight)
{
Canvas.SetTop(source, Maincanvas.ActualHeight - elementHeight);
} */
oneElemntTorched = true;
//MessageBox.Show(this.pinTextBox.ActualHeight.ToString() + ", " + this.pinTextBox.ActualWidth.ToString());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.