【问题标题】:How Draw rectangle in WPF?如何在 WPF 中绘制矩形?
【发布时间】:2011-05-19 14:02:10
【问题描述】:

我需要在画布上绘制矩形。 我知道怎么画。但我没来得及这样做会画上 360 度

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

编辑:

我的行动:

LeftMouseDown in x=50;y=50(按下) 将鼠标移动到 100;100 - 现在可以了 MoveMouse 到 30;150 或 MoveMouse 到 10;10 - 现在我不能这样做,但我需要它

【问题讨论】:

  • 你的意思是你想知道如何旋转一个矩形?
  • 我有一种感觉,他正在尝试 3d 旋转
  • 不!我想让鼠标画一个矩形。但无论它可以向各个方向绘制什么
  • 如何定义矩形起点?鼠标左键向下?

标签: c# wpf


【解决方案1】:

除非您需要一个旋转的矩形,否则我不会费心使用变换。只需将 Left 和 Top 设置为最小 x 和 y,宽度设置为 max-x,高度设置为 maxy-y。

<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】:

步骤:

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

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

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

此流程将允许您单击(设置矩形的角),拖动并释放设置对角,移动鼠标旋转矩形并单击固定矩形。

使用 RenderTransform: 放置和旋转矩形比在矩形上设置边距或 Canvas.Left 更容易。

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

【讨论】:

  • 厄诺,我明白了。但是 Canvas.left\top 有问题。变换 - 很好,我就能确定点击矩形?
  • 我不太确定你在问什么,但 Rectangle 有一个 MouseLeftButtonUp 事件。
【解决方案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;
    }

【讨论】:

    【解决方案4】:
    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;
            }
        }
    
    
    }
    

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        【解决方案6】:
        <Polygon Points="25,0 5,30 45,30"
                 Fill="Red"
                 Stroke="Black"
                 StrokeThickness="2" />
        

        【讨论】:

        • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票。
        • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。请阅读tourHow do I write a good answer?
        【解决方案7】:

        也许我错了,但我认为这可行:

              <Rectangle Width="200" Height="50" Fill="Black">
                <Rectangle.RenderTransform>
                    <RotateTransform CenterX="0" CenterY="0" Angle="45"></RotateTransform>
                </Rectangle.RenderTransform>
            </Rectangle>
        

        【讨论】:

          猜你喜欢
          • 2013-01-24
          • 2021-11-13
          • 1970-01-01
          • 2019-03-11
          • 2023-02-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多