继承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里面的休眠机制,能够避免一些系统底层的未知原因导致的错误。
























