如何在WinForms中绘制形状

我正在尝试编写类似绘画的程序。 您可以通过选择所需的形状来绘制填充的形状,单击图片框并拖动鼠标以获得所需的大小。 但是当我拖动时, 这可能会发生。 当我使用refresh(); ,形状 – 以前绘制 – 删除自己。 我该怎么做才能画出填充的形状?

 private void CizimPicture_MouseDown(object sender, MouseEventArgs e) { Cursor = Cursors.Cross; if (e.Button == MouseButtons.Left) { cizim = true; } X1 = eX; Y1 = eY; } private void CizimPicture_MouseUp(object sender, MouseEventArgs e) { Cursor = Cursors.Default; cizim = false; } private void CizimPicture_MouseMove(object sender, MouseEventArgs e) { if (!cizim) return; if (cizim == true) { X = eX; Y = eY; X2 = (eX - X1); Y2 = (Y1 - eY); if (dikdörtgen == true) { resmim.FillRectangle(renk.Brush, X1, Y1, X2, -Y2); } if (elips == true) { resmim.FillEllipse(renk.Brush, X1, Y1, X2, -Y2); } } } 

我查找了既简单又有效且没有找到任何内容的示例代码。 您不需要屏幕外位图或CreateGraphics ,但您需要处理跟踪鼠标位置,绘制到屏幕,并将绘制的形状添加到Eric建议的形状列表中。 要处理交互式绘图,您需要在表单处理程序中存储鼠标状态,初始单击位置和当前矩形:

 bool mouseDown; Point clickPos; Rectangle rect; 

然后当用户点击时,记住初始位置:

 private void MouseDown(object sender, MouseEventArgs e) { mouseDown = true; clickPos = e.Location; rect = new Rectangle(clickPos, new Size(0, 0)); } 

当用户拖动鼠标时,创建一个包含开始和当前位置的矩形:

 private void MouseMove(object sender, MouseEventArgs e) { if (mouseDown) { this.Invalidate(rect); if (e.Location.X > clickPos.X && e.Location.Y > clickPos.Y) { rect = new Rectangle(clickPos.X, clickPos.Y, e.Location.X - clickPos.X, e.Location.Y - clickPos.Y); } else if (e.Location.X > clickPos.X && e.Location.Y < clickPos.Y) { rect = new Rectangle(clickPos.X, e.Location.Y, e.Location.X - clickPos.X, clickPos.Y - e.Location.Y); } else if (e.Location.X < clickPos.X && e.Location.Y < clickPos.Y) { rect = new Rectangle(e.Location.X, e.Location.Y, clickPos.X - e.Location.X, clickPos.Y - e.Location.Y); } else if (e.Location.X < clickPos.X && e.Location.Y > clickPos.Y) { rect = new Rectangle(e.Location.X, clickPos.Y, clickPos.X - e.Location.X, e.Location.Y - clickPos.Y); } this.Invalidate(rect); } } 

当用户释放鼠标时,停止绘图:

 private void MouseUp(object sender, MouseEventArgs e) { mouseDown = false; } 

Windows窗体中最重要的第1条规则是: 仅在Paint事件中绘制到屏幕 。 永远不会在MouseMoved事件中绘制:

 private void Paint(object sender, PaintEventArgs e) { e.Graphics.FillRectangle(Brushes.DarkGray, rect); } 

完成此操作后,创建一个表单List并在MouseUp事件中添加当前矩形,并在Paint事件中绘制所有矩形。 您还可以在MouseMoved进行一些优化,以仅使更改的屏幕区域无效,而不是旧的和新的矩形。