如何在WPF中绘制矩形?

How Draw rectangle in WPF?

提问人:Mediator 提问时间:5/19/2011 最后编辑:Mediator 更新时间:1/18/2021 访问量:76043

问:

我需要在画布上绘制矩形。 我知道如何画画。但我没有这样做,会画一个 360 度

例。蓝色、淡紫色、绿色,它们是同一个矩形,例如我改变了颜色 红点是起始位置矩形。

enter image description here

编辑:

我的操作:

x=50 中的 LeftMouseDown;y=50 (按) MoveMouse 设置为 100;100 - 现在工作了 将鼠标移动到 30;150 或 MoveMouse 到 10;10 - 现在我不能这样做,但我需要它

C# WPF

评论

0赞 Jake Pearson 5/19/2011
你的意思是你想知道如何旋转矩形吗?
0赞 Maverik 5/19/2011
我有一种感觉,他试图在3D中旋转
0赞 Mediator 5/19/2011
不!我想让鼠标画一个矩形。但无论它能向各个方向画什么
0赞 Phil Gan 5/19/2011
如何定义矩形起点?鼠标左键向下?

答:

-1赞 metalcam 5/19/2011 #1

也许我错了,但我认为这可以工作:

      <Rectangle Width="200" Height="50" Fill="Black">
        <Rectangle.RenderTransform>
            <RotateTransform CenterX="0" CenterY="0" Angle="45"></RotateTransform>
        </Rectangle.RenderTransform>
    </Rectangle>
2赞 Emond 5/19/2011 #2

步骤:

  1. 在 MouseLeftButtonDown 上:如果不旋转:添加一个矩形,其左上角位于鼠标坐标处,其高度和宽度由顶角和鼠标坐标之间的差值计算得出。将布尔值设置为 true 以指示您正在绘图。如果要旋转:通过将旋转布尔值设置为 false 来停止旋转。

  2. 在 MouseMove 上:检查鼠标左键是否仍处于按下状态并且您正在绘图(上一步的布尔值)。重新计算矩形的宽度和高度。如果要旋转,请通过计算释放按钮的点、RenderTransformOrigin 和鼠标的当前位置之间的角度来调整矩形的旋转。(使用 Vector.AngleBetween()

  3. 在 MouseLeftButtonUp 上:如果绘图为 true,则将绘图布尔值设置为 false,并将旋转布尔值设置为 true。

此流程将允许您单击(设置矩形的一角),拖动并松开以设置对角,移动鼠标以旋转矩形,然后单击以修复矩形。

使用 RenderTransform 放置和旋转矩形:这比在矩形上设置 margins 或 Canvas.Left 要容易得多。

如果您需要帮助,请告诉我。

评论

0赞 Mediator 5/19/2011
Erno,我明白了。但是 Canvas.left\top 有问题。转换 - 很好,我将能够确定对矩形的点击?
0赞 Emond 5/19/2011
我不太确定你在问什么,但 Rectangle 有一个 MouseLeftButtonUp 事件。
2赞 Phil Gan 5/19/2011 #3

您实际上不需要这样旋转 - 只需根据您的鼠标位置调整矩形的高度、宽度和左上角即可。

这对您来说可能是一个很好的起点:

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;
    }
40赞 Kris 5/19/2011 #4

除非你需要一个旋转的矩形,否则我不会费心使用变换。只需将 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;
}

评论

2赞 Charmie 2/4/2014
不明白这是怎么回事。我只是复制粘贴,它就像魔术一样工作。现在我必须明白这一点。正是我需要的。非常感谢
0赞 Quincy 12/4/2017
哦,那个鬼鬼祟祟的 Background='Transparent'
0赞 Mediator 5/19/2011 #5
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;
        }
    }


}
0赞 Alamakanambra 1/28/2020 #6

如果有人感兴趣,这是 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" />

0赞 Amir Touitou 1/18/2021 #7
<Polygon Points="25,0 5,30 45,30"
         Fill="Red"
         Stroke="Black"
         StrokeThickness="2" />

评论

3赞 Mark Rotteveel 1/18/2021
请不要只发布代码作为答案,还要解释你的代码是做什么的,以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更好,并且更有可能吸引赞成票。
0赞 Tomer Shetah 1/18/2021
虽然此代码可以回答问题,但提供有关它如何和/或为什么解决问题的其他上下文将提高答案的长期价值。请阅读导览以及如何写出好的答案?