继承PictureBox控件做动态背景,再次打开却报错不显示

网安智编 厦门萤点网络科技 2026-03-13 00:17 28 0
近日项目,需要用到动态的GIF做背景。于是从继承了一个控件,希望以最少的代码解决动态背景的问题。 起先一切都顺利,用的Image属性很快就能够搞定一切,能够支持的图片格式也基本满足要求,遂以为一切大功告成。工作完成,我需要将背景图片等信息保...

继承PictureBox控件做动态背景,再次打开却报错不显示

近日项目,需要用到动态的GIF做背景。于是从继承了一个控件,希望以最少的代码解决动态背景的问题。

起先一切都顺利,用的Image属性很快就能够搞定一切,能够支持的图片格式也基本满足要求,遂以为一切大功告成。工作完成,我需要将背景图片等信息保存,然后在另外一个程序中打开、运行(一个设计时效果,一个运行时效果)。然而,再次打开时,程序报错:GDI+中出现一般性错误( error in GDI+),报错的代码是base.Paint(e),也就是执行基类的Paint函数时出错。

保存图片的代码是这样的:

 ms = new ();

this.Image.Save(ms, Image.);

byte  = ms.();

ms.Close();

 value = node..("Image");

  = .();

value.(node..());

.(value);

打开是其逆过程:

 value = .("Image") as ;

if (value == null)

byte ;

 = .(value.);

if (. > 0)

 ms = new ();

this.Image = Image.(ms);

ms.Close();

自认为这样的代码不会有错的,除非反持续化过程中图片的格式发生了改变。可是跟踪下去,发现持续化前后图片类型的GUID是相同的,由此肯定图片格式没有出错。

那问题在哪里?

的异常报告里面显示,是在Image.()这个函数里面出错了,查MSDN,没有任何有用的信息。于是,一搜才知道,原来不少人都遇到了这个问题。于是兴奋,以为会有很好的解决方法。可惜失望了,遇到这个问题的人不少,可有解决方法的却寥寥无几。似乎我找到的唯一的一个解决办法就是使用Load()函数代替动态创建图片,这显然不能满足我的需求(我需要将图片也保存到XML字段中)。

无奈,只能自己想办法。

找不到问题的原因(不能跟踪,系统代码),就只能猜测。我的思路是:我仅仅保存了Image属性的图片,也许,Image属性还有其它分量。那么,我应当保存整个Image属性,而不仅仅是其引用的图片。

于是修改代码,保存属性的代码如下:

if (this.Image != null)

.("IsSet", "1");

  = .(this);

  = .Find("Image", false);

if ( != null)

 ms = new ();

  = new ();

 obj = .(this);

.(ms, obj);

ms.Seek(0, 0);

byte  = ms.();

ms.Close();

 value = node..("Image");

  = .();

value.(node..());

.(value);

else

.("IsSet", "0");

恢复属性的代码:

byte ;

 = .(value.);

if (. > 0)

 ms = new ();

  = new ();

 obj = .(ms);

  = .(this);

  = .Find("Image", false);

if ( != null)

.(this, obj);

ms.Close();

编译,通过;运行,保存成功;关闭,再次打开,GIF在动,激动啊!

总结:我把整个属性以二进制的形式保存下来,这些内容相当于是从内存里面抠出来的,等到需要的时候再次写回内存,类似于XP里面的休眠机制,能够避免一些系统底层的未知原因导致的错误。