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

问题描述:

我找到的样本代码在这里窗体上图:

I found sample code here for drawing on a form:

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

作为后续这一要求(发现哪些控件是$ b $拖动鼠标所记载的b用户的矩形下):

As a followup to this requirement (discovering which controls are beneath a rectangle described by the user dragging the mouse):

似乎是我的控件的位置和我的MouseDown的位置和-Up事件之间的不匹配

...我想提供用户即时/关于他们即将选择
正是不断的反馈(当/如果他们松开鼠标按钮)。我想不只是画下鼠标的
运动的路线,但是画正由他们mousewrangling努力所描述的矩形。

...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.

我想的MouseMove事件,上面再加码从两个环节,可以做的伎俩,但是,这是被炒得经常/它会带来性能上的一个恶毒的影响?如果是这样,这将是挂钩较好的情况下,或将定时器是去这里的方式?

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? If so, what would be a preferable event to hook, or would a timer be the way to go here?

这个代码,改编自下面约翰的例子(唯一的区别是计算器诱导基地电话。*被注释掉了,我改变了颜色从红色到黑色(以斯滕达尔没有提及意)),作品除了的,以前绘制的矩形松开鼠标后,再次显示。 IOW,第一个矩形绘制完美 - 用鼠标点击了(按预期)消失。然而,当我通过按下鼠标左键,再次拖累和权,的第一个的矩形显示器描述一个矩形!而这将继续发生。 - 每个的前面绘制的矩形被记住并带回时,正在制定一个新的矩形中脱颖而出

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. IOW, the first rectangle draws perfectly - it disappears with the mouse up click (as intended). 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.

公共部分Form1类:表格
{
私人点? _开始;
私人矩形_previousBounds;

public partial class Form1 : Form { private Point? _start; private 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()会做你想要什么。性能不是一般的问题 - 只要保持小而干净

ControlPaint.DrawReversibleFrame() will do what you want. Performance is not generally a problem - just keep it small and clean.

-
编辑:增加了一个代码示例。 StackOverflowException表明什么是错的 - 但没有看到你的,不能直接回答

-- Added a code sample. StackOverflowException indicates something is wrong - but without seeing yours, can't answer directly.

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);
}