Silverlight Expression[转]

*这篇文章基于 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 示例应用程序
图 1 示例应用程序
图 2 显示了支持 Silverlight 应用程序的体系结构。主编程接口是 JavaScript DOM API。它允许对 Silverlight XAML 内部触发的事件作出反应(比如内容加载完成或动画结束时)。也可以调用方法操作表示层(比如启动动画或暂停视频播放)。在它下方是 XAML 分析引擎。分析器创建内存中的 XAML DOM 供表示核心使用,该核心负责处理 XAML 定义的图形和动画呈现。此外,运行时间包含了播放 WMV、WMA 和 MP3 多媒体内容所需的 Codec。
图 2 Silverlight 体系结构
图 2 Silverlight 体系结构
最后,运行库包含了管理呈现过程的表示核心。此显示运行时间内置于支持多种风格 Windows 和 Mac OS X 的浏览器插件中,使用之前讨论的任意浏览器。最终产生了一个可以插入浏览器并通过 JavaScript 编写脚本的独立图形和媒体呈现引擎。
Back to top

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>
 
Back to top

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),并使用事件参数获知按下的是哪个键。
Back to top

转换、媒体和动画
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,指示引擎继续动画,在进行过程中逆转,使得圆形从宽到窄再到宽,而不是重复从宽到窄的转换。
Back to top

简单的 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 简单的视频播放器 (单击该图像获得较小视图)
图 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 最终用户体验。
Back to top

Silverlight 服务器应用程序
如果说把 Silverlight 只看作一种在浏览器中嵌入丰富内容的客户端技术,并不十分公平。这些丰富的功能已经可以通过使用封闭插件获得,如 Java Applets、ActiveX® 控件或 Flash 应用程序。相比较而言,由于用户界面是以基于文本的 XAML 定义,而且通过使用 JavaScript 达到可编程性,因此 Silverlight 是一种开放的技术。它允许开发人员轻易地构建与后端服务器交互的应用程序。
以天气预报应用程序为例。如果想在客户端创建天气预报应用程序,可以构建一个使用 Web 服务的 Java 小程序、ActiveX 控件或 Flash 应用程序,将其部署入客户端。然而,这增加了客户端和服务器通信的需要。如果数据源是付费订阅服务,该怎么办?应用程序部署人员必须验证所有数据服务访问者的许可证,这将占用构建域特定业务逻辑的时间。
然而,如果应用程序可以在服务器端组装,并且所有数据传回客户端,问题就迎刃而解了。使用 Expression Blend 这样的工具,应用程序用户界面的模板可以组装和表达为 XAML。开发人员在运行时就可以收集相关数据并将其插入模板,将最终的 XAML 返回至客户端并呈现。客户端不需要任何逻辑或连接(当然启动时与服务器的初始连接除外),部署和管理客户端也因此会相对容易。
Back to top

构建天气预报应用程序
这一部分将介绍如何构建简单的 XAML 文件以实现天气预报应用程序(请参见图 8)。完成后的天气预报应用程序,将为特定的邮政编码呈现三日的气温预报。该邮政编码作为浏览器内地址的参数传送至应用程序。它还会呈现天气的图形表现形式、正确的日期、邮政编码所在地名称,以及天气数据的动画。天气预报应用程序的所有 XAML 清单都可以在《MSDN 杂志》网站中找到。
图 8 Silverlight 天气预报应用程序
图 8 Silverlight 天气预报应用程序 (单击该图像获得较小视图)
图 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 代码将用指定邮政编码的实时日期和温度覆盖它们。
Back to top

定义淡入动画
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;
 
Back to top

创建 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。
Back to top

将 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。
Back to top

摘要
本文深入介绍了 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 开发人员中心
Back to top

 
Download Image NEW: Explore the sample code online! - or - 代码下载位置: Silverlight2007_06.exe (300KB)
posted @ 2007-08-05 19:01  RicoRui  阅读(591)  评论(0编辑  收藏  举报