提问人:Mediator 提问时间:5/19/2011 最后编辑:Mediator 更新时间:1/18/2021 访问量:76043
如何在WPF中绘制矩形?
How Draw rectangle in WPF?
问:
我需要在画布上绘制矩形。 我知道如何画画。但我没有这样做,会画一个 360 度
例。蓝色、淡紫色、绿色,它们是同一个矩形,例如我改变了颜色 红点是起始位置矩形。
编辑:
我的操作:
x=50 中的 LeftMouseDown;y=50 (按) MoveMouse 设置为 100;100 - 现在工作了 将鼠标移动到 30;150 或 MoveMouse 到 10;10 - 现在我不能这样做,但我需要它
答:
也许我错了,但我认为这可以工作:
<Rectangle Width="200" Height="50" Fill="Black">
<Rectangle.RenderTransform>
<RotateTransform CenterX="0" CenterY="0" Angle="45"></RotateTransform>
</Rectangle.RenderTransform>
</Rectangle>
步骤:
在 MouseLeftButtonDown 上:如果不旋转:添加一个矩形,其左上角位于鼠标坐标处,其高度和宽度由顶角和鼠标坐标之间的差值计算得出。将布尔值设置为 true 以指示您正在绘图。如果要旋转:通过将旋转布尔值设置为 false 来停止旋转。
在 MouseMove 上:检查鼠标左键是否仍处于按下状态并且您正在绘图(上一步的布尔值)。重新计算矩形的宽度和高度。如果要旋转,请通过计算释放按钮的点、RenderTransformOrigin 和鼠标的当前位置之间的角度来调整矩形的旋转。(使用 Vector.AngleBetween()
在 MouseLeftButtonUp 上:如果绘图为 true,则将绘图布尔值设置为 false,并将旋转布尔值设置为 true。
此流程将允许您单击(设置矩形的一角),拖动并松开以设置对角,移动鼠标以旋转矩形,然后单击以修复矩形。
使用 RenderTransform 放置和旋转矩形:这比在矩形上设置 margins 或 Canvas.Left 要容易得多。
如果您需要帮助,请告诉我。
评论
您实际上不需要这样旋转 - 只需根据您的鼠标位置调整矩形的高度、宽度和左上角即可。
这对您来说可能是一个很好的起点:
XAML:
<Canvas x:Name="MyCanvas"
Background="White"
IsHitTestVisible="True"
MouseDown="Canvas_MouseDown"
MouseMove="Canvas_MouseMove"
MouseUp="Canvas_MouseUp">
</Canvas>
代码隐藏:
private bool _mouseDown = false;
private Rectangle _current;
private Point _initialPoint;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
_mouseDown = (e.ButtonState == MouseButtonState.Pressed)
&& (e.ChangedButton == MouseButton.Left);
if (!_mouseDown)
return;
_current = new Rectangle();
_initialPoint = e.MouseDevice.GetPosition(MyCanvas);
_current.Fill = new SolidColorBrush(Colors.Blue);
MyCanvas.Children.Add(_current);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (!_mouseDown)
return;
Point position = e.MouseDevice.GetPosition(MyCanvas);
_current.SetValue(Canvas.LeftProperty,
Math.Min(position.X, _initialPoint.X));
_current.SetValue(Canvas.TopProperty,
Math.Min(position.Y, _initialPoint.Y));
_current.Width = Math.Abs(position.X - _initialPoint.X);
_current.Height = Math.Abs(position.Y - _initialPoint.Y);
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
_mouseDown = false;
}
除非你需要一个旋转的矩形,否则我不会费心使用变换。只需将 Left 和 Top 设置为最小 x 和 y,将 width 设置为 max-x,将 height maxy-y 设置为 maxy。
<Canvas x:Name="canvas" MouseDown="Canvas_MouseDown" MouseMove="Canvas_MouseMove" MouseUp="Canvas_MouseUp" Background="Transparent" />
private Point startPoint;
private Rectangle rect;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
startPoint = e.GetPosition(canvas);
rect = new Rectangle
{
Stroke = Brushes.LightBlue,
StrokeThickness = 2
};
Canvas.SetLeft(rect,startPoint.X);
Canvas.SetTop(rect,startPoint.Y);
canvas.Children.Add(rect);
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if(e.LeftButton == MouseButtonState.Released || rect == null)
return;
var pos = e.GetPosition(canvas);
var x = Math.Min(pos.X, startPoint.X);
var y = Math.Min(pos.Y, startPoint.Y);
var w = Math.Max(pos.X, startPoint.X) - x;
var h = Math.Max(pos.Y, startPoint.Y) - y;
rect.Width = w;
rect.Height = h;
Canvas.SetLeft(rect, x);
Canvas.SetTop(rect, y);
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
rect = null;
}
评论
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace SilverlightApplication1
{
public partial class MainPage : UserControl
{
public MainPage()
{
// Required to initialize variables
InitializeComponent();
mainCanvas.MouseLeftButtonDown+=new System.Windows.Input.MouseButtonEventHandler(MainPage_MouseLeftButtonDown);
mainCanvas.MouseLeftButtonUp+=new System.Windows.Input.MouseButtonEventHandler(MainPage_MouseLeftButtonUp);
mainCanvas.MouseMove+=new System.Windows.Input.MouseEventHandler(MainPage_MouseMove);
SolidColorBrush myBrush = new SolidColorBrush(Colors.Green);
_curRectangle.Rect.Stroke = myBrush;
_curRectangle.Rect.StrokeThickness = 4;
_curRectangle.Rect.Fill = myBrush;
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
}
private void elipse_Click(object sender, System.Windows.RoutedEventArgs e)
{
// TODO: Add event handler implementation here.
}
RealRect _curRectangle = null;
private void MainPage_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
_curRectangle = new RealRect((int)e.GetPosition(sender as Canvas).X, (int)e.GetPosition(sender as Canvas).Y, false);
mainCanvas.Children.Insert(0, _curRectangle.Rect);
_curRectangle.StartRect();
}
private void MainPage_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (_curRectangle != null)
{
_curRectangle.ClearStartTemp();
_curRectangle = null;
}
}
private void MainPage_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (_curRectangle != null)
{
_curRectangle.EndX = (int)e.GetPosition(sender as Canvas).X;
_curRectangle.EndY = (int)e.GetPosition(sender as Canvas).Y;
_curRectangle.MakeReal();
}
//exampleRectangle.Rect.Width = - Canvas.GetLeft(exampleRectangle.Rect);
//exampleRectangle.Rect.Height = - Canvas.GetTop(exampleRectangle.Rect);
}
}
}
工作类
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Windows;
namespace SilverlightApplication1
{
public struct Point
{
public static readonly Point Empty;
public Point(int x, int y) { _x = x; _y = y; }
int _x;
public int X
{
get { return _x; }
set { _x = value; }
}
int _y;
public int Y
{
get { return _y; }
set { _y = value; }
}
}
public class RealRect
{
Rectangle mRect = new Rectangle();
#region Class Local Variables
private SilverlightApplication1.Point mStart;
public SilverlightApplication1.Point MStart
{
get { return mStart; }
set { mStart = value; }
}
private SilverlightApplication1.Point mEnd;
private SilverlightApplication1.Point mRealStart;
private SilverlightApplication1.Point mRealEnd;
private System.Windows.Size mRealSize;
private bool isStatus = false;
public bool IsStatus
{
get { return isStatus; }
set { isStatus = value; }
}
private SilverlightApplication1.Point mTempPoint;
#endregion
public RealRect(int x, int y, bool start)
{
mTempPoint = new SilverlightApplication1.Point(x, y);
IsStatus = false;
mEnd = Point.Empty;
mRealEnd = Point.Empty;
}
public void ClearStartTemp()
{
IsStatus = false;
mTempPoint = Point.Empty;
}
public void StartRect()
{
IsStatus = true;
mStart = mTempPoint;
mRealStart = mTempPoint;
}
/// <summary>
/// Ending X Value of rectangle
/// </summary>
public int EndX
{
set { mEnd.X = value; }
}
/// <summary>
/// Ending Y Value of rectangle
/// </summary>
public int EndY
{
set { mEnd.Y = value; }
}
/// <summary>
/// Get the corrected rectangle
/// </summary>
public Rectangle Rect
{
get
{
MakeReal();
return mRect;
}
}
public void MakeReal()
{
//Started top left, ended bottom right
if (mEnd.X > mStart.X && mEnd.Y > mStart.Y)
{
mRealStart = mStart;
mRealEnd = mEnd;
mRealSize = new Size(mRealEnd.X - mRealStart.X, mRealEnd.Y - mRealStart.Y);
// return;
}
//Started bottom right, ended top left
else if (mEnd.X < mStart.X && mEnd.Y < mStart.Y)
{
mRealEnd = mStart;
mRealStart = mEnd;
mRealSize = new Size(mRealEnd.X - mRealStart.X, mRealEnd.Y - mRealStart.Y);
// return;
}
//Started top right left, ended bottom left
else if (mEnd.X < mStart.X && mEnd.Y > mStart.Y)
{
mRealStart.X = mEnd.X;
mRealStart.Y = mStart.Y;
mRealEnd.X = mStart.X;
mRealEnd.Y = mEnd.Y;
mRealSize = new Size(mRealEnd.X - mRealStart.X, mRealEnd.Y - mRealStart.Y);
// return;
}
//Started bottom left, ended top right
else if (mEnd.X > mStart.X && mEnd.Y < mStart.Y)
{
mRealStart.X = mStart.X;
mRealStart.Y = mEnd.Y;
mRealEnd.X = mEnd.X;
mRealEnd.Y = mStart.Y;
mRealSize = new Size(mRealEnd.X - mRealStart.X, mRealEnd.Y - mRealStart.Y);
// return;
}
Canvas.SetLeft(mRect, mRealStart.X);
Canvas.SetTop(mRect, mRealStart.Y);
mRect.Width = mRealSize.Width;
mRect.Height = mRealSize.Height;
}
}
}
如果有人感兴趣,这是 UWP 的解决方案。(根据@Kris答案)。
它适用于鼠标、触摸和笔。
代码隐藏:
private Point startPoint;
private Rectangle rect;
private void canvas_PointerPressed(object sender, PointerRoutedEventArgs e)
{
startPoint = e.GetCurrentPoint(canvas).Position;
rect = new Rectangle()
{
Stroke = new SolidColorBrush(Colors.LightCoral),
StrokeThickness = 5
};
Canvas.SetLeft(rect, startPoint.X);
Canvas.SetTop(rect, startPoint.Y);
canvas.Children.Add(rect);
}
private void canvas_PointerMoved(object sender, PointerRoutedEventArgs e)
{
if (!e.Pointer.IsInContact || rect == null)
return;
var pos = e.GetCurrentPoint(canvas).Position;
var x = Math.Min(pos.X, startPoint.X);
var y = Math.Min(pos.Y, startPoint.Y);
var w = Math.Max(pos.X, startPoint.X) - x;
var h = Math.Max(pos.Y, startPoint.Y) - y;
rect.Width = w;
rect.Height = h;
Canvas.SetLeft(rect, x);
Canvas.SetTop(rect, y);
}
private void canvas_PointerReleased(object sender, PointerRoutedEventArgs e)
{
rect = null;
}
XAML:
<Canvas x:Name="canvas" PointerPressed="canvas_PointerPressed" PointerMoved="canvas_PointerMoved" PointerReleased="canvas_PointerReleased" Background="Transparent" />
<Polygon Points="25,0 5,30 45,30"
Fill="Red"
Stroke="Black"
StrokeThickness="2" />
评论