在Windows窗体上拖动时调整矩形大小

时间:2012-04-17 20:11:00

标签: c# winforms gdi+

我在Windows窗体上绘制了一个矩形,我想使用提供的一个句柄调整它的大小!

enter image description here

Rectangle areaRect = new Rectangle(100,100, 300, 300);
Bool dragging = false;
Point ptOld = new Point(0, 0);

protected override void OnPaint(PaintEventArgs e)
{
  Graphics dcPaint = e.Graphics;
  dcPaint.DrawRectangle(rectPen, areaRect);
}

protected override void OnMouseDown(MouseEventArgs e)
{
  ptOld = new Point(e.X, e.Y);
  dragging = true;
}

protected override void OnMouseMove(MouseEventArgs e)
{
  if(dragging = true) 
  {
    Point ptNew = new Point(e.X, e.Y);
    Int32 handleSelected = GetSelectedHandle(ptNew);

   // Lets say I want to resize this rectangle using Handle 2 now.
    if(handleSelected == 2) 
    {
      // I am resizing this rectangle Width
      areaRect.X += ptNew.X - ptOld.X;
      areaRect.Width -= ptNew .X - ptOld.X;

      this.Invalidate();
    }
  }
}

protected override void OnMouseUp(MouseEventArgs e)
{
  dragging = false;
}

它会给我这样的效果。哪个是对的,

enter image description here

我怎么想在这里做一个小调整,我想改变这个矩形的高度,当我移动点2时,我的点7应该保持原样,像这样的东西.. 。 类似地,当我移动点4时,我的点5应该是完整的,依此类推第7点和第2点。

enter image description here

任何想法,如何继续,因为如果我改变高度,我的点7位置也会改变?

2 个答案:

答案 0 :(得分:1)

在WinForms中使用这样的MouseMove并不是很顺利。

在调整大小之前,您基本上需要对矩形的引用。

我添加了以下代码来跟踪矩形和8个可拖动点:

private Point GetHandlePoint(int value) {
  Point result = Point.Empty;

  if (value == 1)
    result = new Point(areaRect.Left, areaRect.Top);
  else if (value == 2)
    result = new Point(areaRect.Left, areaRect.Top + (areaRect.Height / 2));
  else if (value == 3)
    result = new Point(areaRect.Left, areaRect.Bottom);
  else if (value == 4)
    result = new Point(areaRect.Left + (areaRect.Width / 2), areaRect.Top);
  else if (value == 5)
    result = new Point(areaRect.Left + (areaRect.Width / 2), areaRect.Bottom);
  else if (value == 6)
    result = new Point(areaRect.Right, areaRect.Top);
  else if (value == 7)
    result = new Point(areaRect.Right, areaRect.Top + (areaRect.Height / 2));
  else if (value == 8)
    result = new Point(areaRect.Right, areaRect.Bottom);

  return result;
}

private Rectangle GetHandleRect(int value) {
  Point p = GetHandlePoint(value);
  p.Offset(-2, -2);
  return new Rectangle(p, new Size(5, 5));
}

以下是我重写表单代码的方法:

private Rectangle areaRect = new Rectangle(100, 100, 300, 300);
private Rectangle oldRect;
private int dragHandle = 0;
private Point dragPoint;

public Form1() {
  InitializeComponent();
  this.DoubleBuffered = true;
}

protected override void OnMouseDown(MouseEventArgs e) {
  for (int i = 1; i < 9; i++) {
    if (GetHandleRect(i).Contains(e.Location)) {
      dragHandle = i;
      oldRect = areaRect;
      dragPoint = GetHandlePoint(i);
    }
  }
  base.OnMouseDown(e);
}

protected override void OnMouseMove(MouseEventArgs e) {
  if (dragHandle == 1) {
    // to do
  } else if (dragHandle == 2) {
    int diff = dragPoint.X - e.Location.X;
    areaRect = new Rectangle(oldRect.Left - diff, oldRect.Top, oldRect.Width + diff, oldRect.Height);
  } else if (dragHandle == 7) {
    int diff = dragPoint.X - e.Location.X;
    areaRect = new Rectangle(oldRect.Left, oldRect.Top, oldRect.Width - diff, oldRect.Height);
  }

  if (dragHandle > 0)
    this.Invalidate();

  base.OnMouseMove(e);
}

protected override void OnMouseUp(MouseEventArgs e) {
  dragHandle = 0;
  base.OnMouseUp(e);
}

protected override void OnPaint(PaintEventArgs e) {
  e.Graphics.DrawRectangle(Pens.Red, areaRect);
  for (int i = 1; i < 9; i++) {
    e.Graphics.FillRectangle(Brushes.DarkRed, GetHandleRect(i));
  }
  base.OnPaint(e);
}

发布的代码只执行Point#2和#7,但这应该为您提供一些逻辑。我确信这些代码可以改进,它只是一个有效的例子。

答案 1 :(得分:1)

虽然这有点旧,但这是第一个(也是我发现的唯一有用的)这类任务的结果。

我使用上面的示例来增强和实施经过测试的解决方案。在我的例子中,我也想让矩形严格地在另一个矩形内。具体来说,我是在PictureBox中绘制的,我希望它永远不会出现在图片之外。这就是max_width和max_height对应的内容。

请注意,它有时会有点滑稽 - 当在某些方向上达到最小尺寸时,它会在另一个方向上重新调整尺寸。我决定我喜欢这种行为,它应该是一个功能。 :)

protected void pictureBox1_OnMouseMove(object sender, MouseEventArgs e)
{
        // Where I started - where I stopped
        int x_diff = dragPoint.X - e.Location.X;
        int y_diff = dragPoint.Y - e.Location.Y;

        // Minimum values
        int small_offset = 5;
        int left = small_offset;
        int top = small_offset;
        int width = small_offset;
        int height = small_offset;

        // Max values
        int max_width = this.pictureBox1.Image.Width;
        int max_height = this.pictureBox1.Image.Height;

        if (dragHandle == 1)
        {
            left = Math.Max(oldRect.Left - x_diff, left);
            top = Math.Max(oldRect.Top - y_diff, top);
            width = Math.Min(Math.Max(oldRect.Width + x_diff, width), max_width - left - small_offset);
            height = Math.Min(Math.Max(oldRect.Height + y_diff, height), max_height - top - small_offset);
        }
        else if (dragHandle == 2)
        {
            left = Math.Max(oldRect.Left - x_diff, left);
            top = oldRect.Top;
            width = Math.Min(Math.Max(oldRect.Width + x_diff, width), max_width - left - small_offset);
            height = oldRect.Height;
        }
        else if (dragHandle == 3)
        {
            left = Math.Max(oldRect.Left - x_diff, left);
            top = oldRect.Top;
            width = Math.Min(Math.Max(oldRect.Width + x_diff, width), max_width - left - small_offset);
            height = Math.Min(Math.Max(oldRect.Height - y_diff, height), max_height - top - small_offset);
        }
        else if (dragHandle == 4)
        {
            left = oldRect.Left;
            top = Math.Max(oldRect.Top - y_diff, top);
            width = oldRect.Width;
            height = Math.Min(Math.Max(oldRect.Height + y_diff, height), max_height - top - small_offset);
        }
        else if (dragHandle == 5)
        {
            left = oldRect.Left;
            top = oldRect.Top;
            width = oldRect.Width;
            height = Math.Min(Math.Max(oldRect.Height - y_diff, height), max_height - top - small_offset);
        }
        else if (dragHandle == 6)
        {
            left = oldRect.Left;
            top = Math.Max(oldRect.Top - y_diff, top);
            width = Math.Min(Math.Max(oldRect.Width - x_diff, width), max_width - left - small_offset);
            height = Math.Min(Math.Max(oldRect.Height + y_diff, height), max_height - top - small_offset);
        }
        else if (dragHandle == 7)
        {
            left = oldRect.Left;
            top = oldRect.Top;
            width = Math.Min(Math.Max(oldRect.Width - x_diff, width), max_width - left - small_offset);
            height = oldRect.Height;

        }
        else if (dragHandle == 8)
        {
            left = oldRect.Left;
            top = oldRect.Top ;
            width = Math.Min(Math.Max(oldRect.Width - x_diff, width), max_width - left - small_offset);
            height = Math.Min(Math.Max(oldRect.Height - y_diff, height), max_height - top - small_offset);
        }


        if (dragHandle > 0)
        {
            areaRect = new Rectangle(left, top, width, height);
            this.Invalidate();
        }
}