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

时间:2012-04-29 04:33:01

标签: c# winforms drawing mouseevent

我在这里找到了用于在表单上绘图的示例代码:

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

作为此要求的后续行动(发现哪些控件位于由...描述的矩形下方) 用户拖动鼠标):

There seems to be a mismatch between the location of my controls and the location of my MouseDown and -Up events

...我想为用户提供关于他们将要选择的内容的即时/持续反馈 (当/如果他们释放鼠标按钮)。我想不只是在鼠标后面画一条线 移动,但绘制他们的鼠标纠缠所描述的矩形。

我认为MouseMove事件加上上面两个链接的代码可以解决这个问题,但这种情况经常被解雇/会对性能造成恶意影响吗?如果是这样,那么什么是一个更好的事件来挂钩,或者计时器是什么方式去这里?

更新

这段代码改编自下面John的例子(唯一的区别是对于base. *的StackOverflow引起的调用被注释掉了,我把颜色从红色改为黑色(没有引用Stendahl的意思)),作品除了,释放鼠标后再次显示先前绘制的矩形。 IOW,第一个矩形完美绘制 - 它随着鼠标单击(按预期)消失。但是,当我通过按下鼠标左键并向下并向右拖动来描述第二个矩形时,再次显示第一个矩形!而且这种情况将继续发生 - 每个以前绘制的矩形都会被记住,并在绘制新矩形时恢复原状。

公共部分类Form1:表单 {     私人点? _开始;     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); 
} 

}

1 个答案:

答案 0 :(得分:1)

ControlPaint.DrawReversibleFrame()会做你想要的。性能通常不是问题 - 只需保持小而干净。

- 编辑:添加了代码示例。 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);
}