C#:从PictureBox中删除Paint事件

时间:2015-02-22 10:34:24

标签: c# winforms events paint picturebox

抱歉我的英语不好。

我有一个图片框,我绘制了100000个形状(但可能还有更多)。 绘图在图片框的Paint Handler中进行。

问题是:当我调整表单的大小(图片框所在的位置)时,使用包含它的面板的滚动条,来自另一个应用程序,......调用绘图处理程序... 但是油漆过程需要相当长的时间,用户必须等到油漆完成......

我尝试了下面的内容:

  • 创建一个我绘制形状的位图
  • 在绘图处理程序中,我复制图片框中的位图

注意:图片框的大小和内容可能会发生变化,因此位图也必须更改。 位图的创建+位图的恢复使应用程序比以前更慢:

Bitmap bmp = new Bitmap(picturebox.Width, picturebox.Height);
// draw in Graphics.FromImage(bmp);
picturebox.Invalidate();
bmp.Dispose();

我也试过布尔标志:canRedraw。 当图片框的内容发生变化时,我将其设置为true,然后我调用picturebox.Invalidate()。在paint处理程序中,我检查是否(canRedraw),如果是,我重绘内容(和canRedraw = false),否则我什么也没做。 但是使用这个最后的解决方案,当我使用表单制作内容时,我的图片框已被清除......

你知道我怎么能做到这一点:

  

如果您是一种更改图片框内容的方法,那么您可以重绘图片框,否则您将保留图片框的可视内容不变

你能帮助我吗?

非常感谢:)

2 个答案:

答案 0 :(得分:1)

如果您没有使用PictureBox的任何其他功能,请尝试将其替换为您自己的UserControl。然后在UserControl中执行以下步骤:

  1. 将控件的DoubleBuffered属性设置为True
  2. 始终检查e.ClipRectangle属性以获取需要重绘的区域。然后遍历您的形状集合,并为每个形状,尝试确定它是否与ClipRectangle相交。我不知道你有什么样的形状,但是大多数形状都有相当快的实现,包括多边形,可以检查两个多边形是否相交。 this article中有一篇关于多边形交集的好文章,包括c#代码。 (请注意,如果您的形状是矩形,圆形或三角形,则交叉点问题变得更容易,计算速度更快)
  3. 仅在与ClipRectangle相交时才绘制形状。

答案 1 :(得分:0)

除了简化Paint dotNet建议另外一种方法就是你尝试过的,但是你需要做正确的事:

是的,执行在[{1}}事件中绘制Bitmap,这将被不必要地调用,然后仍然需要过多时间!相反,当您知道数据已更改并需要重新绘制时,请仅绘制

你没有告诉我们你画的是什么,但绘图应该是这样的:

Paint

只要您想再次绘制数据,请调用此函数!

现在,您可以将void drawStuff() { Bitmap bmp = new Bitmap(pictureBox.ClientSize.Width, pictureBox.ClientSize.Height); using (Graphics G = Graphics.FromImage(bmp) ) { // do all your drawing stuff here!! } pictureBox.Image = bmp; } 事件留空,如果Paint由系统缓存,您仍然可以使用ImagePictureBox.Zoom ..