一次不成功的尝试,使用WEBBROWSER控件显示SVG
项目中需要在窗口应用程序中显示和操作SVG,我想到的有三种方法:
1,自行开发和实现对SVG的显示和操作
这种方法需要工作比较多,涉及对SVG标准的理解,根据应用的需要选择实现部分(毕竟标准的范围太大了),以及使用相应的图形实现,例如DIRECTX,OPENGL或JAVA AWT/SWING, WINDOWS GDI等渲染SVG。
如果项目的目标是提供一个可重用的SVG渲染器,或者在实现SVG范围比较小,功能比较特殊的情况下可以采用。因此没有考虑这种方法。
2,采用第三方SVG实现
使用BATIK可以比较方便的创建支持SVG的JAVA应用程序。在SVG WIKI中也有一些基于C#的SVG实现,例如Sharp Vector Graphics,
不过在2003年4月发布0.3后就没有再更新过,只能参考使用。
3,在应用程序中嵌入浏览器页面
第三种方法是利用浏览器或浏览器插件的SVG功能,将浏览器嵌入窗口应用中使用。这个方法看上去最简单,但实际问题也最多。
首先是发布后必须保证安装的机器上的浏览器也能够显示SVG(例如IE需要安装了ASV等其它插件)。其次调试比较困难,涉及应用程序,浏览器控件,SVG插件等。
最后,如果要从应用程序操作SVG,或SVG的状态显示到窗口的控件中,就需要实现应用窗口和脚本之间的通讯,这在以前是比较麻烦的。
好在.NET FRAMEWORK2.0中提供的WEBBROWSER控件中其提供了脚本和窗口之间的互操作功能,
例如在窗口中调用脚本
webBrowser1.Document.InvokeScript("test", new String[] { "called from client code" });
其中test函数为页面中的JS函数,接收一个字符串参数
function test(message) { alert(message); }
而在脚本中调用窗口函数也很方便:
<button οnclick="window.external.Test('called from script code')">call window code from script</button>
其中
Test是webBrowser1所在窗口中的一个函数
这似乎表明使用WEBBROWSER控件在.NET FRAMEWORK2.0窗口应用程序中能够很方便的显示和操作SVG了,但实际使用中问题依然很多。
WEBBROWSER控件对HTML可以使用多种方式装载,包括Navigate方法
webBrowser1.Navigate("test.html");
或者直接设置DocumentText
webBrowser1.DocumentText =
"<html><head><script>" +
"function test(message) { alert(message); }" +
"</script></head><body><button " +
"οnclick=/"window.external.Test('called from script code')/">" +
"call client code from script code</button>" +
"</body></html>";
或从一个流中输入
StreamReader sr = new StreamReader("test.html");
webBrowser1.DocumentStream = sr.BaseStream;
对于这三种方式,WEBBROWSER控件都可以正确显示HTML文档的内容。而改为SVG后,即使安装了ASV的IE也无法显示SVG内容。
只好将SVG嵌入HTML中,
<embed id="bindsvg" src="test.svg" width="600" height="400" type="image/svg+xml"></embed>
然后再作为HTML显示。
情况略有改善,SVG的外形轮廓被显示出来,这是因为HTML中指明嵌入了一个SVG对象,但IE没有找到SVG文件,尽管它和HTML放在了同一个目录下。
这可能和浏览器的域安全特性有关?但作为本地执行的应用应该没有这个问题吧。
将地址改为URL地址后,
<embed id="bindsvg" src="http://localhost/testproject/test.svg" width="600" height="400" type="image/svg+xml"></embed>
SVG终于被显示出来。但是作为窗口应用程序,希望能够显示本地的SVG内容,而不是WEB页面。这个问题实际上还是没有解决。
即使使用这种方法,在操作中也出现很多问题,特别是在使用SVG页面中的操作时,应用程序变得很不稳定,大约不到十次操作就会没有响应了,而且不知道是WEBBROWSER控件的问题,
还是ASV插件的问题,调试也变得很困难。
在这次不成功的尝试后,我终于放弃了使用这种方式的努力。