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

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

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

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

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

…我想为用户提供关于他们将要选择的内容的即时/持续反馈(何时/如果他们释放鼠标按钮)。 我想不仅仅是在鼠标移动后绘制一条线,而是绘制正在描述的矩形。

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

UPDATE

这段代码改编自John的下面的示例(唯一的区别是StackOverflow-引发对base。*的注释被注释掉了,我将颜色从红色变为黑色(没有引用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); } 

}

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