2012-04-17 64 views
1

我在Windows窗体上绘制了矩形,我想使用提供的其中一个手柄调整大小。在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点的位置也被改变了吗?

+0

您是否尝试重新计算高度,同时保持比例? – SimpleVar 2012-04-17 20:27:40

+0

是的,在拖动点2&7的情况下,我想重新计算高度,同时保持比例,在拖动4和5的情况下,我想重新计算宽度 – Pankaj 2012-04-17 20:57:08

+0

然后在拖动开始时将比率保存为双倍,并且在一个变化时乘以或除(取决于宽度/高度或高度/宽度)高度/宽度与新宽度/高度。如果宽度= 10,高度= 50,则将比率设置为5,并在更改宽度时将高度设置为宽度* 5。更改高度时,请将宽度设置为高度/ 5。 – SimpleVar 2012-04-17 22:53:03

回答

1

像这样在MouseMove上绘图在WinForms中不会很流畅。

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

我下面的代码添加到跟踪矩形和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); 
} 

张贴的代码只做点#2和#7,但是这应该给你一些工作的逻辑。我确信这个代码可以改进,这只是一个工作的例子。

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(); 
     } 
} 
相关问题