【问题标题】:Drawing Ellipse on Canvas with "negative" width/height using mouse events使用鼠标事件在画布上以“负”宽度/高度绘制椭圆
【发布时间】:2015-02-22 09:09:57
【问题描述】:

在 MouseDownEvent 上,我设置了要绘制的椭圆的左上角。

public MyCircle(Point location)
    {
        ellipseObject = new Ellipse
        {
            Stroke = Brushes.Black,
            StrokeThickness = 2,
            Margin = new Thickness(location.X, location.Y, 0, 0)
        };
    }

然后在 MouseMoveEvent 上更新 Width 和 Height 属性,只要我不将鼠标移动到 Ellipse 左上角的上方或/和左侧,它就可以正常工作,在这种情况下,我会遇到这些属性的异常不能是负数(这当然很有意义)。

public void Draw(Point location)
    {
        if (ellipseObject != null)
        {                
            ellipseObject.Width = location.X - ellipseObject.Margin.Left;
            ellipseObject.Height = location.Y - ellipseObject.Margin.Top;               
        }
    }

画线不存在问题:

public void Draw(Point location)
    {
        lineObject.X2 = location.X;
        lineObject.Y2 = location.Y;
    }

我知道这是微不足道的,但我完全坚持这一点。我应该如何处理绘制椭圆?

【问题讨论】:

  • 为什么不使用 Math.Abs​​ 去除负数?
  • 这样,Ellipse 的增长方向将与我想要的相反,而不是抛出异常。我需要实现类似 Paint 的功能。

标签: c# .net wpf


【解决方案1】:

我在尝试创建裁剪工具时遇到了这个确切的问题。问题是您需要为光标从起点变为负 X 或负 Y 时创建 if 语句。对于初学者,您需要有一个全局点,将其标记为“起点”。还要指定一个全局当前点位置,我们将在稍后讨论。

public Point startingPoint;
public Point currentPoint;

然后,确保您在尝试放置椭圆的任何控件上都有 onMouseDown 事件。

private void control_MouseDown(object sender, MouseEventArgs e)
    {
       startingPoint.X = e.X;
       startingPoint.Y = e.Y;
    }

然后,您需要在 MouseMove 事件中创建 if 语句来检查点(当前鼠标位置或起点)是否具有较低的 X/Y 值

private void control_MouseMove(object sender, MouseEventArgs e)
    {
          //The below point is what we'll draw the ellipse with.
          Point ellipsePoint;
          Ellipse ellipseObject = new Ellipse();
          currentPoint.X = e.X;
          currentPoint.Y = e.Y;
         //Then we need to get the proper width/height;
          if (currentPoint.X >= startingPoint.X)
          {
                 ellipsePoint.X = startingPoint.X;
                 ellipseObject.Width = currentPoint.X - startingPoint.X;
          }
          else
          {
                ellipsePoint.X = currentPoint.X;
                ellipseObject.Width = startingPoint.X - currentPoint.X;
          }
          if (currentPoint.Y >= startingPoint.Y)
          {
                ellipsePoint.Y = startingPoint.Y;
                ellipseObject.Height = currentPoint.Y - startingPoint.Y;
          }
          else
          {
                ellipsePoint.Y = currentPoint.Y;
                ellipseObject.Height = startingPoint.Y - currentPoint.Y;
          }
           ellipseObject.Stroke = Brushes.Black;
           ellipseObject.StrokeThickness = 2;
           ellipseObject.Margin = new Thickness(ellipsePoint.X, ellipsePoint.Y, 0, 0);
    }

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    分别保存原点,并将Ellipse的Margin的X和Y属性设置为鼠标位置,将Width和Height设置为鼠标到原点的距离。

    未经测试:

    public MyCircle(Point location)
    {
        ellipseObject = new Ellipse
        {
            Stroke = Brushes.Black,
            StrokeThickness = 2,
            Margin = new Thickness(location.X, location.Y, 0, 0)
            Tag = new Point(location.X, location.Y)
        };
    }
    
    public void Draw(Point location)
    {
        if (ellipseObject != null)
        {                
            Point o = (Point)ellipseObject.Tag;
            double x = Math.Min(location.X, o.Left);
            double y = Math.Min(location.Y, o.Top);
            double width = Math.Abs(Math.Max(location.X, o.Left) - x);
            double height = Math.Abs(Math.Max(location.Y, o.Top) - y);
            ellipseObject.Margin.X = x;
            ellipseObject.Margin.Y = y;
            ellipseObject.Width = width;
            ellipseObject.Height = height;               
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-07
      • 2011-04-18
      • 2021-12-13
      • 2017-02-28
      • 1970-01-01
      • 2014-06-11
      • 2018-01-23
      • 1970-01-01
      相关资源
      最近更新 更多