无论哪种以 Web 为核心点技术,与广泛的计算机以及设备兼容都十分重要。尽管 Silverlight 还在发展过程中,它已经在下面几个系统中运行良好:
- Windows 计算机:Silverlight 可以运行在 Windows Vista 和 Windows XP 的个人计算机上,支持所有主流浏览器
- Mac 计算机:Silverlight 可以运行在装有 OS X 10.4.8 及以上版本的 Mac 计算机上,但要有 Intel 硬件(而不是老的 PowerPC 硬件)
- Linux 计算机:Silverlight 本身目前尚不能在 Linux 上运行,但 Mono 团队正在创建 Silverlight 的开源 Linux 实现。这个项目叫作 Moonlight,且受到了微软的关键支持
运行 Silverlight 程序只需有 Silverlight 浏览器插件就可以了(可在 http://www.silverlight.net 下载)。
创建 Silverlight 程序则需要 Visual Studio 2010,它提供对 Silverlight 3 的完整支持。你也可以选择使用 Expression Blend(它是面向图形的设计工具)构建和测试 Silverlight 程序。Expression Blend 适用于那些花大量时间创建吸引别人目光的效果的图形设计者,而 VS 对以编码为主的开发人员而言是最理想的开发工具。
创建 Silverlight 解决方案
- 新建一个 Silverlight 应用程序,填写解决方案的名称
- VS 将会询问你是否需要创建一个主机网站。如果想创建一个 ASP.NET 网站来承载 Silverlight 应用(而不只是简单的 HTML 文件),应选中 "Host the Silverlight application in a new website” 选项
- 如果你不提供网站名称,默认情况下是项目名称加上 .Web
- 更改项目类型也可以创建一个无项目的 ASP.NET 网站或一个 ASP.NET Web 项目。无论哪种方式都可以提供相同的功能承载 Silverlight 内容
如果步骤和上述相同,现在可以得到一个单独的解决方案,它含有 2 个项目,如下:
Silverlight 编译
当你创建一个 Silverlight 解决方案时,VS 会生成一个新的 ASP.NET 网站,它可以容纳常规的 Web 表单、HTML 页面以及 Web 服务。但是这个网站与以前你所见过的网站的不同处在于,现在它可以承载 Silverlight 内容。
要了解这是如何运作的,需要知道更多关于 Silverlight 编译过程的知识。当你编译上图的解决方案时,将发生以下事情:
- Silverlight 项目将被编译为 DLL 文件(本例的话,csc.exe 编译器会创建一个 Silverlight Application 1.dll 文件)
- 接着,这个程序集将被放入一个名为 XAP 文件的特殊应用程序包。XAP 文件包含了项目的 DLL 程序集、你正在使用的依赖项程序集以及应用程序声明文件 AppMainfest.xml,它列出应用程序所包含的文件。如果你的 Silverlight 项目中添加了其他内容的文件(如图片),它们将自动嵌入到 XAP 文件
- 最终,VS 会将 XAP 文件复制到 ASP.NET 网站里的 ClientBin 文件夹下。一旦你的 Silverlight 已经位于 ClientBin 中,就可以在 ASP.NET 网站里访问到它了
这些步骤可以保证你的 ASP.NET 应用程序总是能获取最新版本的 Silverlight 项目。从技术上说,你无需将 XAP 文件放置到 ClientBin 目录中,但这是区分 Silverlight 内容和网站的其他内容的一个比较方便的做法。
理解 XAP 文件
XAP 是一个 ZIP 压缩包,你重命名为 .zip 文件的话就可以打开此文件,并查看里面的内容。
XAP 文件有两个明显的有点:
- 压缩 Silverlight 内容:Silverlight 只有到达客户端时才会解压缩,所以可缩短应用程序的下载时间。
- 简化部署:只需将 XAP 文件以及包含 Silverlight 内容区域的 HTML 文件复制到 Web 服务器,无需担心遗漏了相关的程序集或资源文件
然而,有一个潜在的障碍。当你的 Web 服务器承载 Silverlight 应用程序时,必须将它设置为允许 XAP 文件类型的请求。在 IIS 7 中,该文件类型默认是包含的,前提是你的系统为 Windows Server 2008、Windows 7、带有 Service Pack 1 的 Windows Vista。如果是早期的 IIS ,或者操作系统不支持,或是其他类型的 Web 服务器,就需要添加一个文件类型来将 .xap 扩展名映射为 MIME 类型 application/x-silverlight-app 。
入口页面
虽然 XAP 简化了部署,但是用户无法直接通过请求 XAP 文件来运行 Silverlight 程序。相反,他们需要跳转到一个实例化 Silverlight 插件的入口页面。
在 ASP.NET 中,创建入口页面有两个办法:
- 创建含有 Silverlight 内容的 HTML 文件:把这些文件放到 ASP.NET 网站目录,和对待其他普通 HTML 文件一样。这种方式唯一的局限性是你的 HTML 文件显然不能包含 ASP.NET 控件,因为它们不能在服务器端被处理
- 把 Silverlight 内容嵌入到 ASP.NET Web 表单中:这种情况下,加载 Silverlight 插件的 <object> 元素被嵌入到动态的 .aspx 页面。这种方式唯一的不足是页面总是要在服务器端被处理。如果页面实际上没有使用任何服务器端 ASP.NET 内容,那么在第一次请求该页面时,就会造成不必要的开销
当然,这两种方式也可以组合使用。如本例中的 SilverlightApplication1TestPage.aspx 和 SilverlightApplication1TestPage.html 。无论哪种情况,Silverlight 插件都以完全相同的方式定义:通过包含在 <div> 元素里的 <object> 元素来定义。
下面是入口页面的简化版本(省略了 CSS 和 JavaScript 错误处理代码):
<%@ Page Language="C#" AutoEventWireup="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>SilverlightApplication1</title>
</head>
<body>
<form id="form1" runat="server" style="height:100%">
<div id="">
<object data="data:application/x-silverlight-2," type="application/x-silverlight-2"
width="100%" height="100%">
<param name="source" value="ClientBin/SilverlightApplication1.xap" />
<param name="onError" value="onSilverlightError" />
<param name="background" value="white" />
<param name="minRuntimeVersion" value="3.0.40818.0" />
<param name="autoUpgrade" value="true" />
<a href="http://go.microsoft.com/fwlink/?LinkId=161376"
alt="Get Microsoft Silverlight" style="border-style:none">
</a>
<iframe id="_sl_historyFrame" style="..."></iframe>
</object>
</div>
</form>
</body>
</html>
这段标记的核心要点是高亮的 DIV 元素。它是 Silverlight 内容区域的占位符。它有一个 <object'> 元素(用于加载 Silverlight 插件)以及一个 <iframe> 元素(用于在浏览器中显示 Silverlight 的内容)。
<object> 元素包含 4 个关键属性:
- data:将此区域标识为 Silverlight 内容区域
- type:指明所需的 Silverlight 版本
- height:…
- width:…
<object> 元素还包含一系列的 <param> 元素,用来指定 Silverlight 插件的其他选项。比如 XAP 文件的位置;JavaScript 子程序运行检查如果插件不能够被加载时要运行的 JavaScript 子程序;Silverlight 区域的背景色;Silverlight 被要求的最小版本号。
<object> 元素中有一些 HTML 标记,它们在 <object> 标签不能被识别或是插件无效时显示。
当这个页面被请求时会发生以下事情:
- 服务器创建所有服务器端对象(本例中包括 ScriptManager 和 Silverlight 控件),并开始常规的 ASP.NET 生命周期
- 在触发所有事件后(且所有事件处理代码已经执行完毕),服务器将页面呈现为常规的 HTML 页面,每一次呈现一个 Web 控件
- 浏览器接收到此页面时,开始处理页面。遇到 <object> 元素,它开始初始化 Silverlight 插件,为 Silverlight 程序下载 XAP 文件,并启动该应用程序
- Silverlight 应用程序在客户端浏览器中运行。不会再有其他服务器端 Web 页面代码被执行,除非用户转向其他页面或者刷新当前页面。
- 如果用户与页面其他的 ASP.NET 控件进行交互,该控件可能会回发页面,这将终止当前正在运行的 Silverlight 程序
- 如果用户使用 ASP.NET AJAX 向 Web 服务器发送请求,这不会打断 Silverlight 程序的运行
下表是给 <object> 元素提供的一系列参数,列出了最重要的部分:
名 称 | 值 |
source | 指向 Silverlight 应用程序 XAP 文件的 URL,这是必需的 |
onError | Silverlight 插件或代码中发生错误时要调用的 JavaScript 事件处理程序 |
background | 绘制 Silverlight 内容区域最底层的背景色,但在同区间 HTML 之上显示 |
minRuntimeVersion | 运行程序客户端必须安装的 Silverlight 最小版本号 |
autoUpgrade | 布尔值,指定 Silverlight 是否尝试更新,比如版本号不满足需要时,默认true |
enableHtmlAccess | 布尔值,表示插件能否访问 HTML 对象模型 |
initParams | 传递自定义初始化信息的字符串,不同页面以不同方式运行 Silverlight 很有用 |
splashScreenSource | XAP 文件下载过程中显示的 XAML 启动动画文件的位置 |
windowless | 布尔值,指示 Silverlight 插件是以窗口模式(默认)运行或无窗口模式 |
onSourceDownadProgressChanged | 当一段 XAP 文件被下载完成后要触发的JS事件(可构建启动进度条) |
onSourceDownloadComplete | 整个 XAP 文件下载完成要触发的 JavaScript 事件处理程序 |
onLoad | XAP 文件中的标记被处理完成且是页面被第一次加载时要触发的 JS 程序 |
onResize | Silverlight 内容区域大小发生变化时要触发的 JavaScript 事件处理程序 |
混合液面
雄心勃勃的 ASP.NET 开发者会用 Silverlight 为已有的 ASP.NET 页面添加新功能(或仅作为装饰)。例如用 Silverlight 制作的广告内容、菜单系统、嵌入式程序(计算器或游戏)。
当处理此类交互时,重要的是理解 Silverlight 应用程序的生命周期!ASP.NET 代码运行在 Web 服务器,控件导致页面回发后,Silverlight 程序终止运行。Web 服务器代码运行完毕后,新版的页面又送回浏览器,此时 Silverlight 程序就重新启动了。这不仅将用户带回了起点,也会增加额外的时间,因为 Silverlight 环境必须完全重新初始化。
使用 ASP.NET AJAX 技术可以避免这样的事情发生。UpdatePanel 是一个非常有用的工具。封装会导致回发的控件,产生 AJAX 的异步请求效果来提交页面的部分代码,当浏览器重新接收到服务器发回的这部分代码,也只会进行一个局部更新,而不会影响 Silverlight 内容。