简体   繁体   English

如何根据鼠标的移动绘制矩形?

[英]How do I draw a rectangle based on the movement of the mouse?

I found sample code here for drawing on a form: 我在这里找到了用于在表单上绘图的示例代码:

http://msdn.microsoft.com/en-us/library/aa287522(v=vs.71).aspx http://msdn.microsoft.com/zh-CN/library/aa287522(v=vs.71).aspx

As a followup to this requirement (discovering which controls are beneath a rectangle described by the user dragging the mouse): 作为此要求的后续措施(发现用户拖动鼠标所描述的矩形下方的控件):

There seems to be a mismatch between the location of my controls and the location of my MouseDown and -Up events 我的控件的位置与MouseDown和-Up事件的位置之间似乎不匹配

...I want to provide the user instant/constant feedback about just what they are about to select (when/if they release the mouse button). ...我想向用户提供他们即将选择的内容的即时/持续反馈(何时/如果他们释放鼠标按钮)。 I want to not just draw a line following the mouse's movement, but draw the rectangle that is being described by their mousewrangling efforts. 我不仅要按照鼠标的移动来画一条线,还要画出它们的鼠标争吵努力所描述的矩形。

I'm thinking the MouseMove event, coupled with code from the two links above, could do the trick, but is that fired too often/would that have a malevolent impact on performance? 我在考虑MouseMove事件,再加上上面两个链接中的代码,可以解决问题,但是触发次数过多/是否会对性能产生恶意影响? If so, what would be a preferable event to hook, or would a timer be the way to go here? 如果是这样,那将是一个更可取的事件挂起,或者计时器将成为此方法?

UPDATE 更新

This code, adapted from John's example below (the only difference is the StackOverflow-inducing calls to base.* are commented out, and I changed the color from red to black (no reference to Stendahl intended)), works except that previously drawn rectangles display again after releasing the mouse. 这段代码改编自以下约翰的示​​例(唯一的区别是,引起StackOverflow的对base的调用已被注释掉,并且我将颜色从红色更改为黑色(无意引用Stendahl)), 除了先前绘制的矩形外释放鼠标后再次显示。 IOW, the first rectangle draws perfectly - it disappears with the mouse up click (as intended). IOW,第一个矩形绘制得很完美-随鼠标单击(按预期方式)消失。 However, when I describe a second rectangle by depressing the left mouse key and dragging down and to the right, the first rectangle displays again! 但是,当我通过按下鼠标左键并向右向下拖动来描述第二个矩形时,第一个矩形会再次显示! And this continues to happen - every previously drawn rectangle is remembered and brought back to the fore when a new rectangle is being drawn. 并继续发生-记住每个先前绘制的矩形,并在绘制新矩形时将其重新显示。

public partial class Form1 : Form { private Point? 公共局部类Form1:表单{private Point? _start; _开始; private Rectangle _previousBounds; 私人Rectangle _previousBounds;

public Form1()
{
    InitializeComponent();
}

private void Form1_MouseDown(object sender, MouseEventArgs e)
{
    _start = e.Location;
    //base.OnMouseDown(e); 

}

private void Form1_MouseMove(object sender, MouseEventArgs e)
{
    if (_start.HasValue)
        DrawFrame(e.Location);

    //base.OnMouseMove(e); 

}

private void Form1_MouseUp(object sender, MouseEventArgs e)
{
    ReverseFrame();
    _start = null;
    //base.OnMouseUp(e); 
}

private void ReverseFrame() 
{ 
    ControlPaint.DrawReversibleFrame(_previousBounds, Color.Black, FrameStyle.Dashed); 
} 

private void DrawFrame(Point end) 
{ 
    ReverseFrame(); 

    var size = new Size(end.X - _start.Value.X, end.Y - _start.Value.Y); 
    _previousBounds = new Rectangle(_start.Value, size); 
    _previousBounds = this.RectangleToScreen(_previousBounds); 
    ControlPaint.DrawReversibleFrame(_previousBounds, Color.Black, FrameStyle.Dashed); 
} 

} }

ControlPaint.DrawReversibleFrame() will do what you want. ControlPaint.DrawReversibleFrame()将做您想要的。 Performance is not generally a problem - just keep it small and clean. 性能通常不是问题,只需保持其小巧清洁即可。

-- EDIT: Added a code sample. -编辑:添加了代码示例。 StackOverflowException indicates something is wrong - but without seeing yours, can't answer directly. StackOverflowException表示有问题-但看不到您的内容,无法直接回答。

private Point? _start;
private Rectangle _previousBounds;

protected override void OnMouseDown(MouseEventArgs e)
{
    _start = e.Location;
    base.OnMouseDown(e);
}

protected override void OnMouseMove(MouseEventArgs e)
{
    if( _start.HasValue ) {
        ReverseFrame();
        DrawFrame(e.Location);
    }

    base.OnMouseMove(e);
}

protected override void OnMouseUp(MouseEventArgs e)
{
    ReverseFrame();
    _start = null;
    base.OnMouseUp(e);
}

private void ReverseFrame()
{
    ControlPaint.DrawReversibleFrame(_previousBounds, Color.Red, FrameStyle.Dashed);

}
private void DrawFrame(Point end)
{
    ReverseFrame();

    var size = new Size(end.X - _start.Value.X, end.Y - _start.Value.Y);
    _previousBounds = new Rectangle(_start.Value, size);
    _previousBounds = this.RectangleToScreen(_previousBounds);
    ControlPaint.DrawReversibleFrame(_previousBounds, Color.Red, FrameStyle.Dashed);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM