-
*这篇文章基于 Silverlight 的预发布版。文中包含的所有信息均有变更可能。
本文讨论:
-
- Silverlight 和 XAML 简介
- 构建简单的 Silverlight 应用程序
- 在服务器上动态生成 Silverlight 应用程序
- 创建 XAML 服务
|
本文使用了以下技术: Silverlight, XAML, JavaScript
|
-
Microsoft 战略中下一代 Web 开发工具的一个关键组件,就是名为 Microsoft® Silverlight™ 的新技术,原代号为“WPF/E”。Silverlight 将 Windows® Presentation Foundation 体验带到 Web 中,提供丰富又令人陶醉的内容,与包括 ASP.NET AJAX 在内的其他 Web 开发环境实现无缝连接。
-
-
为了与 Web 社区尽可能地融合,Silverlight 需要在多个流行的操作系统和最常见的浏览器中成功运行。其结果是,最初发行的版本支持在 Mac OS X 上运行的 Firefox 和 Safari 浏览器,以及在 Windows 上运行的 Firefox 和 Internet Explorer®。随着产品的发展,会支持更多的操作系统和浏览器。除这些功能外,Silverlight 也是完全独立的,不需要依靠其他产品,比如它不需要 Windows Media® Player 进行视频播放,也不需要 Microsoft .NET Framework 3.0 进行 XAML 分析。
-
本文既是对 Silverlight 体系结构的高度概述,又可让您通过构建几个 Silverlight 应用程序获得亲身体验,这一切从一个基本的“Hello World”应用程序开始。之后我将引导您构建简单的媒体播放器。您还将知道作为客户端技术的 Silverlight,如何融入更大的、面向服务器的环境,包括在运行 PHP 或 Java 的服务器上应用的能力。
Silverlight 简介
-
从核心上说,Silverlight 是呈现 XAML 的浏览器插件,以可编写脚本的方式,向浏览器提供其内部的文档对象模型 (DOM) 和事件模型。因此,设计人员可以将含有图形、动画、时间线的 XAML 文档整合在一起,以便开发人员将它们关联到页面代码,实现其功能。由于 XAML 基于 XML,定义下载至客户端的 UI 是基于文本的,因此对搜索引擎和防火墙都很友好。此外,XAML 可以由服务器应用程序在运行时组装和发出,因此不仅提供了丰富的图形体验,而且是高度可自定义和动态的。
-
图 1 是对简单 Silverlight 应用程序的分析,它使用静态的 XAML 文件定义其 UI 和处理事件的 JavaScript。浏览器会实例化插件,并且作为处理过程的一部分,加载 XAML 文件。文件内部的事件(例如单击按钮)将由浏览器捕获并通过 JavaScript 处理。由于 Silverlight 内容的 DOM 已公开,JavaScript 代码也可以动态地更新 Silverlight 内容,改变已呈现内容的状态。
-
图 1 示例应用程序
-
图 2 显示了支持 Silverlight 应用程序的体系结构。主编程接口是 JavaScript DOM API。它允许对 Silverlight XAML 内部触发的事件作出反应(比如内容加载完成或动画结束时)。也可以调用方法操作表示层(比如启动动画或暂停视频播放)。在它下方是 XAML 分析引擎。分析器创建内存中的 XAML DOM 供表示核心使用,该核心负责处理 XAML 定义的图形和动画呈现。此外,运行时间包含了播放 WMV、WMA 和 MP3 多媒体内容所需的 Codec。
-
图 2 Silverlight 体系结构
-
最后,运行库包含了管理呈现过程的表示核心。此显示运行时间内置于支持多种风格 Windows 和 Mac OS X 的浏览器插件中,使用之前讨论的任意浏览器。最终产生了一个可以插入浏览器并通过 JavaScript 编写脚本的独立图形和媒体呈现引擎。
-
XAML 概述
-
XAML 是一种基于 XML 语言,可用于定义图形资源、用户界面、行为、动画等。微软将它作为在 Windows Presentation Foundation 中使用的标记语言推出。Windows Presentation Foundation 是一种面向桌面的技术,属于 .NET Framework 3.0 的一部分,旨在帮助协调设计人员和开发人员在创建应用程序时的工作。
-
一直以来,设计人员使用一套工具和资源创建应用程序,而开发人员则使用自己的另一套工具。工具集的不匹配可能对最终的应用程序产生负面影响。微软推出新的 Expression 工具套件,主要是 Microsoft Expression® Design 和 Microsoft Expression Blend,让专业设计人员可以分别将图形项目和用户界面放在一起,将最终结果表述为 XAML,以便开发人员用此构建应用程序。
-
首次发布的 Silverlight 所使用的 XAML 不同于 Windows Presentation Foundation 使用的 XAML,前者是可用于桌面的完整 XAML 的面向 Web 子集。因此,如果您熟悉 Windows Presentation Foundation XAML,您可能会注意到缺失一些东西,比如 <Window> 标记、页面资源、数据绑定和丰富控件模型。
-
在 XAML 中,元素是用 XML 标记定义的。每个 Silverlight 文档的根级别都是 Canvas 标记,它定义绘制 UI 元素的空间。该 Canvas 应包含 Silverlight 需要的 XML 命名空间声明。
-
- <Canvas xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”></Canvas>
-
-
一个 Canvas 可以有一或多个子项,子 Canvases 又可以创建它们自己的子项。Canvas 子项有相对于其父项的位置,而不是对根 Canvas。下面的示例中,一个 Canvas 包含一个矩形 (Rectangle),该矩形放在距其父项左上角 25 像素的位置。
-
- <Canvas Width=”250” Height=”200”> <Rectangle Canvas.Top=”25” Canvas.Left=”25” Width=”200” Height=”150” Fill=”Black” /></Canvas>
-
-
XAML 内部
-
Silverlight XAML 支持多种形状,能够合成复杂的对象。支持的基本图形包括矩形、椭圆、线条、多边形、复合线和路径。它们大多数都是不解自明的。复合线允许定义一系列相连的线段。路径允许定义一个通过 Canvas 的非线性路径(如同涂鸦)。
-
画笔决定如何在屏幕上绘制对象。用 Fill 绘制内容,用 Stroke 绘制轮廓。画笔分纯色画笔、渐变画笔和图像画笔几种。纯色画笔通过 fill 属性(如前例使用的 Fill="Black")的固定色、或使用 SolidColorBrush 作为附加属性实现(如下所示):
-
- <Rectangle Canvas.Top=”25” Canvas.Left=”25” Width=”200” Height=”150”> <Rectangle.Fill> <SolidColorBrush Color=”Black” /> </Rectangle.Fill> <Rectangle>
-
-
颜色可以通过名称(支持 141 种命名的颜色)或十六进位 RGB 定义。
-
渐变画笔通过在规范化空间中定义渐变域和若干渐变停留来实现。举例来说,假设在灰色阴影中,需要一个线形渐变,从右至左,从黑变白。指定渐变停留 0(规范化线的开端)为黑色、渐变停留 1(规范化线的结束)为白色。Silverlight 就将为您绘制这个渐变。渐变也可以在二维空间中用规范化矩形定义空间来绘制(0,0 为左上,1,1 为右下)。要定义一个二维的填充矩形,左上为红色,右下为黑色,中间是流畅的渐变,使用 XAML 如下:
-
- <Rectangle Width=”200” Height=”150” > <Rectangle.Fill> <LinearGradientBrush StartPoint=”0,0” EndPoint=”1,1”> <LinearGradientBrush.GradientStops> <GradientStop Color=”Red” Offset=”0” /> <GradientStop Color=”Black” Offset=”1” /> </LinearGradientBrush.GradientStops> </LinearGradientBrush> </Rectangle.Fill></Rectangle>
-
-
用 ImageBrushes 也可以绘制对象,图像将被适当地剪切或拉伸。因此,例如可以指定使用 ImageBrush 填充椭圆,使用的 XAML 如下:
-
- <Ellipse Width=”200” Height=”75” > <Ellipse.Fill> <ImageBrush ImageSource=”http://.../logo.jpg” /> </Ellipse.Fill></Ellipse>
-
-
在 XAML 中,文本可以用 TextBlock 标记呈现。这样您可以控制文本的各个方面,如内容、字体、字号、折行等等。以下是一些示例:
-
- <TextBlock>Hello</TextBlock> <TextBlock FontSize=”18”>Hello</TextBlock> <TextBlock FontFamily=”Courier New”>Hello</TextBlock> <TextBlock TextWrapping=”Wrap” Width=”100”> Hello there, how are you? </TextBlock>
-
-
此外,Silverlight 支持用于实现文本输入的键盘事件。在根元素上可以定义键盘事件(KeyDown 或 KeyUp),并使用事件参数获知按下的是哪个键。
-
转换、媒体和动画
-
XAML 允许在对象上定义多种转换。RotationTransform 以定义的角度旋转元素,ScaleTransform 可以用来拉伸或缩小对象,SkewTransform 使其在定义的方向上扭曲定义的量,TranslateTransform 根据定义的矢量移动对象,MatrixTransform 则结合了以上所有转换。
-
转换可以分组,这样,通过将转换定义为组的一部分,可以将多个转换置于对象之上。
图 3 就是一个很好的示例。在此情况下,Canvas 中有 3 个椭圆。由于转换在 Canvas 层次中定义,因此每个椭圆都将被旋转和缩放。
-
使用 MediaElement 标记控制音频和视频内容。此标记具有源属性,指向即将播放的媒体。使用此标记定义的对象提供了许多控制媒体播放的方法和事件。在文章稍后部分中,您将看到用 XAML 构建的简单媒体播放器示例,其中 JavaScript 实现了播放、暂停、停止等用户交互。定义 MediaElement 非常简单:
-
- <Canvas xmlns=”...” xmlns:x=”...”> <MediaElement Source=”xbox.wmv” /> </Canvas>
-
-
在 XAML 中实现动画的方式是定义属性应该如何根据时间线逐渐发生变化。动画定义包含在 Storyboard 中。动画有各种不同的类型,包括变化数字属性的 DoubleAnimation、变化颜色和画笔的 ColorAnimation、变化二维值的 PointAnimation。这些动画可以是线性的,也可以是基于关键帧的。在线性动画中,动画沿着定义的时间线发生流畅的变化。基于关键帧的动画可在离散的值之间移动。
-
图 4 显示了一个随时间改变圆形宽度的简单动画示例。AutoReverse 属性设为 True,指示引擎继续动画,在进行过程中逆转,使得圆形从宽到窄再到宽,而不是重复从宽到窄的转换。
-
简单的 Silverlight 应用程序
-
在 Visual Studio 2005 中,您可以使用 Silverlight 应用程序模板(Silverlight SDK 下载的一部分),轻松构建 Silverlight 应用程序。本文中我使用了 Visual Web Developer™ Express 应用程序,可以
从 MSDN® 下载。
-
本示例是个简单的媒体播放器,播放 WMV 视频内容。它使用 Channel 9 视频(
channel9.msdn.com),但您可以更改为播放您喜欢的任何视频。XAML 十分简单,在
图 5 中可以完整地看到。为简单起见,TextBlock 元素用于“Play”(播放)、“Stop”(停止)和“Pause”(暂停)按钮。
-
MediaElement 标记用于定义视频。它的名称是 mPlayer,其像素设为 640×400。“Source”标记指向一个微软网站提供下载的 WMV 视频。
-
接下来是三个 TextBlock 元素,用于定义“Play”(播放)、“Stop”(停止)和“Pause”(暂停)按钮。这些按钮垂直排列在画布左上方。注意 Canvas.Left 尚未设置,默认为 0。这些 TextBlock 元素定义了单击 (MouseLeftButtonDown) 时引发的 JavaScript 事件处理程序。在它们上面按下鼠标按钮时,Silverlight 将事件传送至浏览器,由 JavaScript 捕获和处理。
-
现在让我们组合成一个应用程序:它使用此 XAML,并使用 Visual Web Developer Express 实现 JavaScript 事件处理程序。要使它工作,需要一个 silverlight.js 文件,该文件可以从 Silverlight SDK 下载中得到,也可以在 MSDN 示例下载网站的任意 Silverlight 示例中得到。
-
使用 Visual Web Developer Express,创建新的 Web 站点。在该站点中创建名为 \js 的文件夹,在其中添加 silverlight.js 文件。右键单击 \js 文件夹并选择“Add New Item”(添加新项)。在新建文件对话框中选择 JScript 文件,并将其称为 eventhandlers.js。
-
然后,右键单击 Solution Explorer 中的项目,单击“Add New Item”(添加新项),创建一个新的 XML 文件,名为 videoplayer.xaml。用
图 5 列出的 XAML 填充。
-
最后,在项目中添加一个新的 HTML 页面,命名为 Default.htm。编辑 HTML 页面,使其加载 JavaScript 库,并用它们创建一个 Silverlight 播放器实例以呈现 XAML 内容。
图 6 显示了 Default.htm 的完整源代码。
-
页面顶端的脚本标记可导入 JavaScript 库、silverlight.js 和 eventhandlers.js。silverlight.js 库管理 Silverlight 插件的下载和实例化。它有浏览器和 OS 抽象,所以您毋须担心;您只需利用 Sys.Silverlight.createObjectEx 函数实现新的 Silverlight 控件。Silverlight 插件本身应该位于分配了 ID 的 DIV 块内部。在这种情况下,包含插件的 DIV 称为 AgControl1Host。实例化 Silverlight 内容时会用到此 ID。
-
Silverlight 插件的实例化方式是创建新的 Silverlight 控件实例,传入大量参数以构造它。有关这些参数的详细信息,请参见 Silverlight SDK。
-
最后一步是实现 JavaScript 函数,该函数处理单击“Play”(播放)、“Stop”(停止)和“Pause”(暂停)按钮时触发的事件。这些代码应放入 eventhandlers.js。
-
- function PlayVideo(sender,args){ var mPlayer = sender.findName(“mPlayer”); mPlayer.Play();}function PauseVideo(sender,args){ var mPlayer = sender.findName(“mPlayer”); mPlayer.Pause();} function StopVideo(sender,args){ var mPlayer = sender.findName(“mPlayer”); mPlayer.Stop();}
-
-
在 XAML 中,Stop TextBlock 将 MouseLeftButtonDown 属性定义为指向 JavaScript:StopVideo。通过创建接受 sender 和 args 参数的同名 JavaScript 函数实现此函数。使用 Silverlight 中的 findName 函数,可以在 DOM 内找到与已命名参数匹配的元素。因此,要停止正在播放的视频,可以使用 findName API 来查找 MediaElement。在 XAML 中,该元素称为 mPlayer。findName API 将返回该对象的引用,可以将其载入 JavaScript var。现在有了引用之后,您可以简单地调用它的 Stop 方法以停止视频播放。播放和暂停功能与之相似。
-
就是这样!简单的视频播放器能立即与 Silverlight 组合在一起。运行应用程序,可以看到类似于图 7 所示的结果。
-
图 7 简单的视频播放器 (单击该图像获得较小视图)
-
图 7 简单的视频播放器 (单击该图像获得较大视图)
-
当然如果希望硬编码视频 URI 到 XAML 里也是可以的,但这不是最可行的方式。让我们看一下将其从静态 HTML 页面更改为活动 Web 窗体,以将视频作为参数接受。
-
第一步,从 XAML 中删除对媒体文件的引用。更改 XAML 中的 MediaElement,删除 Source 属性。完成后应该如下所示:
-
- <MediaElement x:Name=”mPlayer” Width=”640” Height=”400”/>
-
-
然后,在应用程序中创建一个名为 VideoPlayer.aspx 的新 Web 窗体 (ASPX)。此窗体应实体化一个源于 videoplayer.xaml 的 Silverlight 控件,如
图 6 所示。此外,它应包含以下 JavaScript 代码:
-
- <script type=”text/javascript”> function root_Loaded(sender,args) { var mPlayer = sender.findName(“mPlayer”); mPlayer.Source = “<% Response.Write(Request.Params[“VideoURI”]); %>”; mPlayer.Play();}</script>
-
-
XAML 含有一个事件声明,加载 Canvas 时引发该事件。这是由 JavaScript 中的 root_Loaded 事件处理程序捕获的。该函数利用 ASP.NET 将 VideoURI 从服务器上的 HTTP 请求中提取出来,用 VideoURI 填入 JavaScript 函数,从而设置视频源。页面执行时,视频(VideoURI 参数指定)将由 Silverlight 呈现。请注意,这个一个非常简单的示例,没有任何错误处理或过滤,如果您希望自己的应用程序有此类功能,则需要进行添加。
-
注意,在使用如下 URI 调用此页面时:
-
- http://localhost/MSDN1/VideoPlayer.aspx?videouri=xbox.wmv
-
-
ASP.NET 将产生一个包含 JavaScript 块的页面,如下所示:
-
- <script type=”text/javascript”> function root_Loaded(sender,args) { var mPlayer = sender.findName(“mPlayer”); mPlayer.Source = “xbox.wmv”; mPlayer.Play(); } </script>
-
-
之后此 JavaScript 将 xbox.wmv 文件载入 MediaElement,Silverlight 将播放视频。以上说明使用服务器端活动页面(ASPX、PHP 或 Java)可以通过增加灵活性,大大改善 Silverlight 最终用户体验。
-
Silverlight 服务器应用程序
-
如果说把 Silverlight 只看作一种在浏览器中嵌入丰富内容的客户端技术,并不十分公平。这些丰富的功能已经可以通过使用封闭插件获得,如 Java Applets、ActiveX® 控件或 Flash 应用程序。相比较而言,由于用户界面是以基于文本的 XAML 定义,而且通过使用 JavaScript 达到可编程性,因此 Silverlight 是一种开放的技术。它允许开发人员轻易地构建与后端服务器交互的应用程序。
-
以天气预报应用程序为例。如果想在客户端创建天气预报应用程序,可以构建一个使用 Web 服务的 Java 小程序、ActiveX 控件或 Flash 应用程序,将其部署入客户端。然而,这增加了客户端和服务器通信的需要。如果数据源是付费订阅服务,该怎么办?应用程序部署人员必须验证所有数据服务访问者的许可证,这将占用构建域特定业务逻辑的时间。
-
然而,如果应用程序可以在服务器端组装,并且所有数据传回客户端,问题就迎刃而解了。使用 Expression Blend 这样的工具,应用程序用户界面的模板可以组装和表达为 XAML。开发人员在运行时就可以收集相关数据并将其插入模板,将最终的 XAML 返回至客户端并呈现。客户端不需要任何逻辑或连接(当然启动时与服务器的初始连接除外),部署和管理客户端也因此会相对容易。
-
构建天气预报应用程序
-
这一部分将介绍如何构建简单的 XAML 文件以实现天气预报应用程序(请参见图 8)。完成后的天气预报应用程序,将为特定的邮政编码呈现三日的气温预报。该邮政编码作为浏览器内地址的参数传送至应用程序。它还会呈现天气的图形表现形式、正确的日期、邮政编码所在地名称,以及天气数据的动画。天气预报应用程序的所有 XAML 清单都可以在《MSDN 杂志》网站中找到。
-
图 8 Silverlight 天气预报应用程序 (单击该图像获得较小视图)
-
图 8 Silverlight 天气预报应用程序 (单击该图像获得较大视图)
-
文档顶端是打开的 Canvas 标记。这是个基本容器,在上面可以绘制对象。Canvas 不只限于一个,而且用 Canvas 组合相关元素是有用的。因此,举例来说,每一天可以包括图解、最高气温、最低气温和各种标签,所有这些都收集到一个 XAML 模板中。
图 9 是某天的示例。在这种情况下,Canvas 包含了许多 TextBlocks 和 Image 控件。此 canvas 的给定名称为 cnv2,置于屏幕中,不透明度为 0(意味着最初不可见)。它的高度、宽度、左边界和上边界设置使其处于屏幕上特定的位置。
-
TextBlock 用于在 Silverlight 中呈现文本。这里有许多 TextBlock,有的用作硬编码标签,比如存储在名为 lblDegHigh2 和 lblDegLow2 的 TextBlock 中的“°F”标签。在 x:Name 属性中可以找到名称。
-
名为 lblDate2、lblHigh2 和 lblLow2 的 TextBlock 包含占位符信息—目前它们都硬编码为特定的数据和温度,但您的 ASP.NET 代码将用指定邮政编码的实时日期和温度覆盖它们。
-
定义淡入动画
-
Canvas 节点支持触发器,触发响应事件的操作。在这种情况下,Canvas.Triggers 被设置为在页面加载(如下所示)时触发:
-
- <Canvas.Triggers> <EventTrigger RoutedEvent=”FrameworkElement.Loaded”> <BeginStoryboard>...
-
-
这样,当页面加载时,触发器触发,动画 Storyboard 启动。动画 Storyboard 定义动画行为。以下是用在 Canvas (包括特定日期天气的文本占位符和图形)上的动画,名为 cnv1:
-
- <DoubleAnimationUsingKeyFrames BeginTime=”00:00:00” Storyboard.TargetName=”cnv1” Storyboard.TargetProperty=”(UIElement.Opacity)”> <SplineDoubleKeyFrame KeyTime=”00:00:00” Value=”0”/> <SplineDoubleKeyFrame KeyTime=”00:00:01” Value=”1”/> </DoubleAnimationUsingKeyFrames>
-
-
动画类型为 DoubleAnimationUsingKeyFrames。您将在 0 至 1 之间修正 Canvas 及其子项的不透明度(由 UIElement.Opacity 定义),使其在一段时间内淡入。该时间由与动画相关联的关键帧决定。
-
当 XAML 呈现时,Storyboard 将启动,使第一个元素在呈现开始(0 秒时)至 1 秒之后由不透明度 0 淡入至不透明度 1。观察 XAML 您就会发现,其他的 Canvas 将在 1 至 2 秒之间以及 2 至 3 秒之间分别淡入,产生一种逐渐出现的效果。
-
XAML 是一种有效的 XML,因此元素可以由其属性命名,并通过该名称找到它们。因此,举例来说,第一天的高温图形占位符元素将如下所示:
-
- <TextBlock x:Name=”lblHigh1” Width=”67” Height=”59” Canvas.Left=”112” Canvas.Top=”30” FontFamily=”Tahoma” FontSize=”48” FontWeight=”Bold” Foreground=”#FFF64F12” Text=”27” TextWrapping=”Wrap”/>
-
-
此 TextBlock 被命名为 lblHigh1。服务(您将在下一步看到)使用 XMLDocument 加载模板 XAML,找到此名称的节点,利用如下所示的 C# 代码改变其文本属性:
-
- string xpath = “//d:TextBlock[@x:Name=’lblHigh1’]”; xNode = xmlDoc.SelectSingleNode(xpath, mng); string high = myResults[n - 1].MaxTemperatureF; xNode.Attributes[“Text”].Value = high;
-
-
创建 XAML 服务
-
当您在网页上使用 Silverlight 时,控件采用的参数之一是 XAML 呈现的位置。在这种情况下,XAML 是动态的,根据请求天气的邮政编码而变化。因此,您将创建一个 Web 应用程序,产生并返回 XAML,而呈现它的页面将指向此页面。这是构建此 Silverlight 应用程序的第一步。
-
使用 Visual Studio ® 创建新的 Web 项目。添加一个包含 silverlight.js 的 \js 目录,方法与您处理前面的视频播放器相同。为项目添加新的 Web 引用,引用如下定义的 Web 服务:
-
- http://www.webservicex.net/WeatherForecast.asmx?WSDL
-
-
将服务命名为 weatherservice。为项目添加新的 Web 窗体并称之为 Web Form XAMLSource.aspx。选择“添加代码”作为一个独立页面选项。确保代码页顶端有如下一套 using 指令:
-
- using System;using System.Data;using System.Configuration; using System.Collections;using System.Web;using System.Web.Security; using System.Web.UI;using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts;using System.Web.UI.HtmlControls; using System.Xml;using System.Xml.XPath;
-
-
在本节的余下部分,您将为 XAMLSource.aspx 上的 Page_Load 事件处理程序添加代码。首先,将名为 Scene.xaml 的模板加载到一个 XMLDocument 对象:
-
- XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(Server.MapPath(“Scene.xaml”));
-
-
然后,设置读取参数。您将使用查询字符串参数(指定了要求的邮政编码)来调用页面:
-
- http://server/XamlSource.aspx?ZIP=<something>
-
-
要检索参数,可使用以下代码:
-
- string strZip = “98052”;if (Request.Params[“ZIP”] != null) strZip = Request.Params[“ZIP”];
-
-
这将启动本地保存参数化邮编的字符串,并且当它未作为 HTTP 请求的一部分传入时,设置其默认值。下一步,创建对处理天气信息的 Web 服务的调用:
-
- weatherservice.WeatherForecast myWeather = new weatherservice.WeatherForecast(); weatherservice.WeatherForecasts myForecast = myWeather.GetWeatherByZipCode(strZip); weatherservice.WeatherData[] myResults = myForecast.Details;
-
-
此代码创建了一个 Web 服务代理(当添加服务的 WSDL 的引用时,由 Visual Studio 为您创建)的实例,称为 myWeather。Web 服务在 WeatherForecasts 数据结构内返回数据,因此通过调用服务中的 GetWeatherByZipCode 方法(并对其传递一个字符串)创建此数据结构的一个实例(称为 myForecast)。预报对象的 Details 成员是一个 WeatherData 类型的数组,因此 myResults 变量被设置为其实例。
-
下一步是初始化 XMLDocument 以便用 XPath 进行搜索。由于 XML 使用 XAML 架构作为部分元素的命名空间(用 x 做前缀,例如 x:Name),您将需要为页面上的所有元素(包括没有前缀的元素)定义命名空间。例如,您不能搜索与 XPath //TextBlock 匹配的节点,但您可以指定默认的命名空间采用一个新的前缀(此情形下使用 d 表示虚拟),然后搜索使用这个前缀的默认节点,即 //d:TextBlock。代码如下:
-
- NameTable myn = new NameTable(); XmlNamespaceManager mng = new XmlNamespaceManager(new NameTable()); mng.AddNamespace(“d”, “http://schemas.microsoft.com/winfx/2006/xaml/presentation”); mng.AddNamespace(“x”, “http://schemas.microsoft.com/winfx/2006/xaml”);
-
-
现在您已可以使用 XPath,接下来您可以找到包含城市名称的节点,以及将其 Text 属性更改为该邮政编码所标识的服务所在的城市名称。
-
- XmlNode xNode = xmlDoc.SelectSingleNode( “//d:TextBlock[@x:Name=’lblTownName’]”, mng); xNode.Attributes[“Text”].Value = myForecast.PlaceName + “,” + myForecast.StateCode;
-
-
类似地,您可以在其后的三天里循环,找到包含所需位置的占位符节点,并得到其值,把正确的值置于 XML 中,代码如
图 10 所示。
-
现在您使用模板和正确的数据完整填充了您的 XML 文档,最后一步是将其返回给调用方。要完成这一步,需要设置 MIME 类型,将 XMLDocument 对象的内容直接写入响应流,按如下所示:
-
- Response.ContentType = “text/xml”;Response.Write(xmlDoc.InnerXml);
-
-
下一步,删除 Visual Studio 在 ASPX 页面中给您的占位符 HTML。删除 ASPX 文件中第一行之外的所有内容。完成后应该如以下代码所示:
-
- <%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”XamlSource.aspx.cs” Inherits=”_Default” %>
-
-
最后一步是在解决方案中添加一个新的 XML 文件,称为 Scene.xaml。在早先代码中曾提及此文件。得到完整的天气 XAML,并将其粘贴至此文件。现在就可以执行页面了,在浏览器中应该能看到 XAMLSource.aspx 页面返回的 XAML。
-
将 XAML 传送至 Silverlight 前端
-
前面几步构建了模板 XAML,然后构建了使用该 XAML 的 Web 窗体,使用 Web 服务,将 Web 服务调用的结果放入 XAML 中正确的位置。下一步是提供包含 Silverlight 控件的页面,并使其指向此 XAML 服务。
-
打开前几部分使用的站点,添加一个新的 Web 窗体,称为 Default.aspx。在 Default.aspx 中修改 HTML 代码,如
图 11 所示。
-
重要部分在于调用 Silverlight.createObjectEx,在此静态的 videoplayer.xaml 已经由对 XAML 源应用程序的调用取代,在调用中传递 Default.aspx 页面为邮政编码接收的参数:
-
- “WeatherSite/XamlSource.aspx?ZIP=<% if (Request.Params[“ZIP”] == null) Response.Write(“98052”); else Response.Write(Request.Params[“ZIP”]);%>”
-
-
此操作将请求参数放入页面,并将其附加到一个 URL,后者会调用最后一步创建的 XamlSource 页面。随后将对 XamlSource 进行调用,传递邮政编码,获得由 Silverlight 呈现的 XAML 文件。Default.aspx?ZIP=90210 的运行结果见图 8。
-
摘要
-
本文深入介绍了 Silverlight。您也看到一些应用程序,它们不仅仅是鹦鹉学舌式地说“Hello, World”,而是展示了诸如如何用 XAML 构造用户界面,如何与 JavaScript 关联进行交互,如何从单纯的客户端模式转为基于服务器的模式,从而让应用程序更具灵活性。这种方法让您了解到如何创建简单的视频播放器,能接受视频流的 URI 并回放,在博客等环境下使用非常理想。
-
此外,通过天气监视器(有非常简单的客户端分布模型)的形式,您学会了如何构建可感知数据的应用程序。只需要让 Silverlight 组件调用服务器,获得正确的 XAML 并呈现它,从而形成丰富的瘦客户端。
-
虽然 ASP.NET 和微软堆栈为构建这样的 Web 应用程序提供了高效率的平台,本文的下载部分也包含了此应用程序的 Java 版本。此版本提供了与 ASP.NET 版本同样的功能,即使用 Web 服务获取数据,然后将 XAML 加载到 XML Document DOM 中。它随后找出模板数据的适当节点,在将完成的 XAML 写出成为 URI 之前,将他们的值替换为来自 Web 服务的值。随即构造 JSP(未列出),引用此 servlet 的 URL 以使用 Silverlight 呈现 XAML。
-
Silverlight 的 Web 之路才刚刚开始。凭借 XAML 呈现引擎的丰富性,以及使用标准 Web 开发技术的灵活性,Silverlight 非常值得添加到您的开发人员工具箱里。有关详细信息,请关注
MSDN Silverlight 开发人员中心。
-
-