无法在Wpf画布上从右下角到左上角绘制矩形
问题描述:
我正在实现允许用户在运行时通过拖动鼠标在Wpf画布上绘制矩形的功能。我当前能够绘制矩形当我从拖动左上角下鼠标左键,但是当我拖动矩形是不可见从左下角到top.Below鼠标是我使用的XAML代码:无法在Wpf画布上从右下角到左上角绘制矩形
<Canvas x:Name="CanvasContainer" MouseLeftButtonDown="CanvasContainer_MouseLeftButtonDown" MouseLeftButtonUp="CanvasContainer_MouseLeftButtonUp" MouseMove="CanvasContainer_MouseMove" >
<Rectangle x:Name="RectangleMarker" Canvas.Left="0" Stroke="Red" Width="0" Height="0" Panel.ZIndex="1"></Rectangle>
<Line x:Name="LineMarker" Stroke="Red" X1="0" Y1="0" X2="0" Y2="0"></Line>
<Image Canvas.Left="0" Canvas.Top="0" x:Name="PdfImage" RenderTransformOrigin="0.5,0.5" MouseWheel="PdfImage_MouseWheel" ClipToBounds="True" Panel.ZIndex="0">
<Image.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="1" CenterX="0.5" CenterY="0.5" />
</Image.LayoutTransform>
</Image>
</Canvas>
下面是事件根据鼠标位置更新矩形的位置。
private void CanvasContainer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
try
{
Point startPoint = Mouse.GetPosition(CanvasContainer);
Canvas.SetLeft(RectangleMarker, startPoint.X);
Canvas.SetTop(RectangleMarker,startPoint.Y);
}
catch (Exception ex)
{
}
}
private void CanvasContainer_MouseMove(object sender, MouseEventArgs e)
{
try
{
if (e.LeftButton == MouseButtonState.Pressed)
{
Point endPoint = Mouse.GetPosition(CanvasContainer);
Point startPoint = new Point((double)RectangleMarker.GetValue(Canvas.LeftProperty), (double)RectangleMarker.GetValue(Canvas.TopProperty));
double x = Math.Min(startPoint.X, endPoint.X);
double y = Math.Min(startPoint.Y, endPoint.Y);
double width = endPoint.X - startPoint.X;
double height = endPoint.Y - startPoint.Y;
if (width < 0)
{
x = startPoint.X + width;
}
if (height < 0)
{
y = startPoint.Y + height;
}
RectangleMarker.Width = Math.Abs(width);
RectangleMarker.Height = Math.Abs(height);
if (x!=startPoint.X)
{
Canvas.SetLeft(RectangleMarker, x);
}
else if(y!=startPoint.Y)
{
Canvas.SetTop(RectangleMarker, y);
}
}
}
catch (Exception ex)
{
}
}
答
更好的使用路径与RectangleGeometry:
<Canvas Background="Transparent"
MouseLeftButtonDown="CanvasContainer_MouseLeftButtonDown"
MouseLeftButtonUp="CanvasContainer_MouseLeftButtonUp"
MouseMove="CanvasContainer_MouseMove">
<Path Stroke="Red">
<Path.Data>
<RectangleGeometry x:Name="selectionRect"/>
</Path.Data>
</Path>
</Canvas>
后面的代码:
private Point? startPoint;
private void CanvasContainer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var element = (UIElement)sender;
element.CaptureMouse();
startPoint = e.GetPosition(element);
}
private void CanvasContainer_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
((UIElement)sender).ReleaseMouseCapture();
startPoint = null;
}
private void CanvasContainer_MouseMove(object sender, MouseEventArgs e)
{
if (startPoint.HasValue)
{
selectionRect.Rect = new Rect(
startPoint.Value, e.GetPosition((IInputElement)sender));
}
}
答
正如我在评论前面提到你的问题不是绘制,但调整 。
当调整矩形大小时,有4个可能的方向,4个边和4个角。所以这很复杂。
最简单的方法是简单地记住开始鼠标的位置,然后检查哪里是新位置,他们之间绘制矩形。显然,新的鼠标位置可以是任一角落,取决于鼠标相对于起点移动的方向。
所以:
Point _start;
void CanvasContainer_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) =>
_start = Mouse.GetPosition(CanvasContainer);
void CanvasContainer_MouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var mouse = Mouse.GetPosition(CanvasContainer);
Canvas.SetLeft(RectangleMarker, _start.X > mouse.X ? mouse.X : _start.X);
Canvas.SetTop(RectangleMarker, _start.Y > mouse.Y ? mouse.Y : _start.Y);
RectangleMarker.Width = Math.Abs(mouse.X - _start.X);
RectangleMarker.Height = Math.Abs(mouse.Y - _start.Y);
}
}
Math.Abs
将处理调整为正或负的改变,而改变位置,我们还需要一个条件检查,以确定哪个点,开始或新的鼠标,是左上角。
演示:
@Sinatr我不想画第二个矩形,只是要移动现有的矩形。 –
@Sinatr我的意思是绘制矩形,就像我们在绘画工具中做的一样。按下鼠标按钮并拖动以绘制矩形。如果在向下对角线方向(UL到LR)中拖动,则它起作用,但如果我们向上对角线方向拖动(LR到UL),则该矩形不可见。 –