c# - I'm trying to move a Rectangle in a Canvas ( in a WPF app) using the Mouse event but it don't work
问题描述
I develop a wpf application and I have to move a rectangle in a canvas (and the end goal is to make sure my rectangle can not get out of the canvas). So I searched and tried many solutions on the Web, but I was not working yet. Then I tried to rewrite a solution, but it did not work.
<Grid x:Name="mainGrid">
<Canvas x:Name="CanvasImplant" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="27,27,26,0" Height="415">
<Rectangle x:Name="MovableShape" Opacity="0.85" Width="93" Height="62" HorizontalAlignment="left" VerticalAlignment="Top" Margin="930,140" Stroke="Black" StrockThickness="1" MouseDown="MovShp_MouseDown" MouseUp="MovShp_MouseUp" MouseMove="MovShp_MouseMove"/>
</Canvas>
</Grid>
private bool drag = true;
private Point StartPt;
private double newX, newY;
private void MovShp_MouseDown(object sender, MouseButtonEventArgs e)
{
drag = true;
Cursor = Cursors.Hand;
startPt = e.Getposition(CanvasImplant);
Mouse.Capture((UIElement)sender);
}
private void MovShp_MouseUp(object sender, MouseButtonEventArgs e)
{
drag = false;
Cursor = Cursors.Arrow;
Mouse.Capture(null);
}
private void MovShp_MouseMove(object sender, MouseButtonEventArgs e)
{
if (drag)
{
double deltaX = e.GetPosition(CanvasImplant).X - startPt.X;
double deltaY = e.GetPosition(CanvasImplant).Y - startPt.Y;
newX = deltaX + Canvas.GetLeft(MovableShape);
newY = deltaY + Canvas.GetTop(MovableShape);
if (newX < 0)
newX = 0;
else if (newX + MovableShape.ActualWidth > CanvasImplant.ActualWidth)
newX = CanvasImplant.ActualWidth - MovableShape.ActualWidth;
if (newY < 0)
newY = 0;
else if (newY + MovableShape.ActualHeight > CanvasImplant.ActualHeight )
newY = CanvasImplant.ActualHeight - MovableShape.ActualHeight ;
MovableShape.SetValue(Canvas.LeftProperty, newX);
MovableShape.SetValue(Canvas.TopProperty, newY);
}
}
When I click on MovableShape, the mouse becomes a hand and when I release the left mouse button, it becomes an arrow, but when I drag the rectangle, it does not follow the mouse and when I release the click, it do not move.
解决方案
有几件事。
- 您需要在形状上设置填充,否则您的点击事件只会在非常细的边框上触发
- 鼠标移动和鼠标向上事件需要是 Canvas 事件,而不是形状
- 您需要每次在移动事件处理程序中将 startPt 设置为新位置
- 您需要删除形状的边距和水平/垂直位置
- 您需要使用 Canvas 而不是形状来捕获鼠标
这对我有用:
<Grid x:Name="mainGrid" >
<Canvas x:Name="CanvasImplant" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" MouseMove="MovShp_MouseMove" MouseUp="MovShp_MouseUp" Background="Transparent">
<Rectangle Canvas.Left="10" Canvas.Top="20" x:Name="MovableShape" Fill="Transparent" Opacity="0.85" Width="93" Height="62" Stroke="Black"
StrokeThickness="1" MouseDown="MovShp_MouseDown" />
</Canvas>
</Grid>
和处理程序:
private void MovShp_MouseDown(object sender, MouseButtonEventArgs e)
{
drag = true;
Cursor = Cursors.Hand;
startPt = e.GetPosition(CanvasImplant);
Mouse.Capture(CanvasImplant);
}
private void MovShp_MouseUp(object sender, MouseButtonEventArgs e)
{
drag = false;
Cursor = Cursors.Arrow;
Mouse.Capture(null);
}
private void MovShp_MouseMove(object sender, MouseEventArgs e)
{
if (drag)
{
var mp = e.GetPosition(CanvasImplant);
double deltaX = mp .X - startPt.X;
double deltaY = mp .Y - startPt.Y;
var newX = deltaX + Canvas.GetLeft(MovableShape);
var newY = deltaY + Canvas.GetTop(MovableShape);
if (newX < 0)
newX = 0;
else if (newX + MovableShape.ActualWidth > CanvasImplant.ActualWidth)
newX = CanvasImplant.ActualWidth - MovableShape.ActualWidth;
if (newY < 0)
newY = 0;
else if (newY + MovableShape.ActualHeight > CanvasImplant.ActualHeight)
newY = CanvasImplant.ActualHeight - MovableShape.ActualHeight;
Canvas.SetLeft(MovableShape, newX);
Canvas.SetTop(MovableShape, newY);
startPt = mp ;
}
}
推荐阅读
- android-studio - 如何从 Flutter 中的应用名称中删除下划线
- perl - perl 中的“一次”警告是什么?
- apache-spark - 循环 Spark Dataframe,保存结果并使用上一次迭代的结果
- javascript - 如何重构反应中的方法?
- excel - Excel (2010) 将格式化值转换为其等效文本
- awk - 如何用awk跳过两个模式之间的行?
- css - 谷歌自动完成出现在 reactstrap 模式后面
- python - 如何在字典中获取列表值
- go - 有没有办法从 reflect.Func 中提取包路径?
- docker - 如何配置 docker-compose 以便将磁盘挂载到文件夹,而不是本地磁盘