2009-11-20 55 views
1

我有一个Windows窗体,通过幻灯片显示在窗体上显示图像。我这样做的方式是让Panel控件具有它驻留的窗体的大小,并添加一个事件处理函数,用于绘制内存中存在的Image对象。绘制事件处理程序在几次迭代后停止执行

void panel_Paint(object sender, PaintEventArgs e) 
{ 
    if (_bShowImage) 
    { 
    Point leftCorner = new Point((this.Bounds.Width/2) - (_image.Width/2), (this.Bounds.Height/2) - (_image.Height/2)); 

    e.Graphics.DrawImage(_image, leftCorner); 

    _bShowImage = false; 
    } 
} 

当一个新的图像加载和_image引用,我迫使面板重绘:

_bShowImage = true; 
_panel.Refresh(); 

紧接着,图像设置,并从全局变量的间接引用:

_image.Dispose(); 
_image = null; 

我已经看到它有一段时间,说5次迭代,然后panel_Paint()处理程序不被调用。我使用2-3个JPG来显示,我知道它们没有损坏,因为它们在前x次显示效果很好。我已经将面板的Refresh()方法的调试线放在了执行正常的面板上。就好像对处理程序的调用已被删除。有没有人遇到过这个问题?

+0

有没有原因你不使用PictureBox?每次需要重新绘制一点点时,这种方式绘制整个图像会有很多开销......如果您要自己做,我建议至少注意应该重绘的区域从PaintEventArgs获取。 – 2009-11-20 12:59:38

回答

0

将图片放入图片框并以这种方式循环显示它们会不会更聪明,这样您就不会每次都在整个窗口强制重绘?

只是一个想法...

托尼

+0

我最初使用过一个PictureBox,但它会出现同样的问题,所以我决定自己做。 – Michali 2009-11-20 14:49:20

1

这是如此彻底倒退。您可以像现在一样使用绘制事件处理程序。这很好(我说它比picturebox更好),但是你需要放弃_bShowImage和_image.Dispose。在开启新图像之前,您应该先弃置_image。但是,直到那。或者,如果absolutley必须在绘制后立即处理_image,则应改为使用Panel.CreateGraphics来获取可用于立即绘制_image并删除事件的Graphichs对象。

就目前而言 - 这只是令人困惑。另外:.Invalidate()是你几乎总是想要的 - 不.Refresh()。这是自VB6时代以来一直困在很多人心中的东西。

+0

我现在把Paint事件处理放在一边,并去了那个建议。现在至少我们得到了一个地方,因为我得到了一个实际的异常: System.Runtime.InteropServices.ExternalException:在GDI +中发生了一般性错误。 在System.Drawing.Graphics.CheckErrorStatus(的Int32状态) 在System.Drawing.Graphics.DrawImage(图像的图像,的Int32的x,的Int32 Y) 在System.Drawing.Graphics.DrawImage(图像的图像,点点) 我认为这可能是内存泄漏,但我处理了图像。另外,Graphics对象是全局对象,所以我只在最后处理一次。 – Michali 2009-11-20 17:13:16

+1

这听起来也是倒退 - 要么让它保持全局,要处置它,并确保立即将其设置为空,以便在尝试使用它时至少获得空引用异常。或者你把它变成本地的。拥有“全局”处置参考文件是毫无用处的。几乎总是可以忘记忘记.Dispose()。但从来没有处理一些仍在使用中的东西。至少对于你现在的bug追踪:放弃.Dispose()。 – 2009-11-20 18:58:15

相关问题