在开发Silverlight应用程序时,经常需要在应用中集成HTML页面,以提供更丰富的用户交互体验。本文将介绍如何将动态创建的HTML页面集成到Silverlight应用中,并实现Silverlight与HTML页面之间的信息传递。
在开始项目时,对于Silverlight与HTML的交互方式存在误解。在查阅了网络上的示例后,错误地认为Silverlight可以通过一行代码指定要显示的网页URL。然而,事实并非如此。Silverlight只能访问一个HTML(或ASP)页面,即与Silverlight解决方案一起在Visual Studio中自动创建的默认HTML或ASPX页面。所需要做的就是增强这些页面,加入自己的代码。具体使用哪个页面取决于应用在域主机上的web.config文件中设置的默认页面。如果不确定,可以简单地保持两个页面的内容相同。
让从这些默认页面开始。在这个示例中,将展示HTML版本,但同样的方法也适用于ASP页面(包含在示例项目中)。首先,需要在body标签中插入两个参数:
<param name="windowless" value="true" />
<param name="onLoad" value="pluginLoaded" />
第一个参数确保HTML内容可见(否则所有HTML内容都会隐藏在Silverlight表面之后)。第二个参数会在Silverlight应用程序加载时触发HTML页面上的事件(JavaScript函数将处理此事件)。
接下来,需要在页面中添加一个不可见的div元素,它将作为想要显示的动态HTML内容的容器。因此,将添加以下代码行到silverlightControlHost的div下方:
<div id="HTMLContentArea" style="position: absolute; display:none;"></div>
确保将div添加到silverlightControlHost之外,否则动态HTML内容将只在IE兼容性模式下显示。
还需要在页面的script区域包含一些JavaScript函数,以处理按钮点击并与Silverlight应用程序交互。这些函数的大部分将引用将在运行时插入到不可见div容器中的HTML元素,因此不必担心。可以根据自己的需求调整这些函数。
最后,需要添加一个引用CKEditor的JavaScript文件,这样就完成了HTML部分:
<script type="text/javascript" src="ckeditor/ckeditor.js"></script>
(完整的HTML页面请参考示例项目)
这一步将指导完成所有必要的代码,以显示和隐藏任何HTML内容,并与在HTML页面中放置的JavaScript函数进行交互。
首先,需要向项目中添加一个新类,它将作为HTML的接口。所有从HTML页面中的JavaScript函数调用的函数必须带有前缀:
<ScriptableMember()>_
此外,该类需要两个公共属性来存储浏览器中可用显示区域的宽度和高度,以便稍后调整动态HTML内容的大小(这些属性将在Silverlight应用程序的主页面的Load事件中设置,以反映当前的尺寸):
Public HTMLWidth As Double = 0
Public HTMLHeight As Double = 0
两个公共函数(Show_MailEditor和Show_MailViewer)将允许从Silverlight代码的任何位置显示邮件编辑器或查看器。Show_MailViewer将接受两个参数(主题和正文),在邮件查看器中显示。这两个函数首先会创建动态HTML内容,将其插入项目HTML页面中的不可见div中,调整元素大小以适应可用的显示区域,最后使div可见(这将导致HTML页面覆盖浏览器中的Silverlight表面)。
由于CKEditor在运行时加载,它需要一些毫秒来替换分配的textarea元素,所以需要一个计时器来执行短暂的延迟,然后再调整编辑器的大小。最后,需要明确地将焦点设置到动态HTML内容中的一个元素上,否则输入元素只会在第一次调用时工作,并且在任何进一步调用显示HTML页面时会被冻结(不要问为什么...但就是这样!)。
要使这个接口在所有代码位置都可用,像这样在全局模块中创建实例:
Module modGlobal
Public objMailInterface As MailInterface = Nothing
End Module
现在,需要为Silverlight应用程序注册接口以进行脚本编写。在App.xaml.vb的Application_Startup过程中添加以下代码:
objMailInterface = New MailInterface
HtmlPage.RegisterScriptableObject("MailInterface", objMailInterface)
如前所述,应用程序需要在运行时向接口发出可用浏览器显示区域的信号。为此,在MainPage.xaml.vb的MainPage_SizeChanged事件中添加以下代码:
objMailInterface.HTMLHeight = Me.ActualHeight
objMailInterface.HTMLWidth = Me.ActualWidth
现在可以在代码的任何地方调用HTML页面了:
objMailInterface.Show_MailEditor()
//或
objMailInterface.Show_MailViewer("Mail Demo", "Hello World!
")