【原文地址】Silverlight Tutorial Part 3: Using Networking to Retrieve Data and Populate a DataGrid
【原文发表日期】 Friday, February 22, 2008 5:54 AM
这是8个系列教程的第三部分,这系列示范如何使用Silverlight 2的Beta1版本建造一个简单的Digg客户端应用。这些教程旨在按顺序阅读,帮着解释Silverlight的一些核心编程概念。
使用Networking取回Digg故事
Silverlight 2 有内置的networking API,允许Silverlight客户端调用远程的REST, SOAP/WS*, RSS, JSON和XML HTTP服务。Silverlight 2还包含了内置的socket API (System.Net.Sockets),允许Silverlight客户端通过非HTTP协议来通信(对聊天服务等这样的场景非常理想)。
跨域网络访问
Silverlight 2应用在做网络调用时,始终可以回调到它们的“原始(origin)”服务器(意味着它们可以调用下载的应用来自的同域的URL)。 Silverlight 2应用还可以做跨域网络调用(意味着它们可以调用与下载的应用来自的不同的域上的URL),只要远程的web服务器拥有一个XML策略文件,表明客户端是 允许做这些跨域调用的。
Silverlight 2 定义了一个XML策略文件格式,允许服务器管理员精确地控制一个客户端应该有些什么访问权。Silverlight 2 也遵守默认的Flash跨域策略文件格式-这意味着你可以使用Silverlight 2 来调用web上已经允许Flash客户端跨域访问的任何现有的远程REST, SOAP/WS*, RSS, JSON 或 XML 端点(end-point )。
Digg.com有一套非常酷的通过HTTP通信的Digg APIs。因为他们有一个Flash跨域策略文件在他们的服务器上,我们可以直接从我们的Silverlight Digg 客户端应用中调用它们(而不要求我们通过我们的web服务器去访问他们的API)。
Digg.com 主题 Feed API
我们要允许终端用户使用我们的应用输入一个搜索主题(譬如,“Programming”),然后点击“搜索”按钮,从Digg.com取回符合条件的前N条故事:
我们可以使用Digg.com List Stories REST API feed API 来实现。它在URL中接受一个主题参数(譬如,GET /stories/topic/programming),然后返回一个匹配那个主题的XML格式的Digg故事集。点击这里看一下这个XML格式的例子。
使用 System.Net.WebClient 来异步调用Digg REST Feed
在上面的搜索按钮被点击之后,我们将处理它的Click事件,从WaterMarkTextBox控件中取回要搜索的主题字符串,然后启动一个发向Digg的网络调用,为那个主题取回相应的XML列表。
Silverlight 在 System.Net 命名空间下包含了WebClient辅助类(该类也在完整的.NET 框架下)。我们可以使用这个类从URL异步下载内容。异步下载Digg故事的好处是,在等待远程服务器的回复时,我们的UI不用阻塞或变得没有反应(允许 我们拥有一个非常流畅的用户体验)。
通过WebClient类执行异步下载,我们要做的是注册一个DownloadStringCompleted事件处理方法(它将在请求的内容被下载之后被调用),然后调用WebClient.DownloadStringAsync(url) 辅助方法来开始下载:
使用上面的代码,我们现在就可以异步取回一个XML数据的字符串,内含有关用户想要的任何主题的Digg故事。
使用LINQ to XML把XML格式的Digg故事分析成Story类对象
至此,我们可以取回Digg故事数据的XML片段了,下一步将是对其进行分析(parse),并将它转换成我们可以操作和绑定到控件上的DiggStory对象。
我们将首先定义一个DiggStory类,该类拥有可以映射到来自Digg的XML内容上的属性(我们将利用C#新的 "自动属性"的特性来实现):
然后我们就可以使用LINQ (是内置于 Silverlight 2中的)和 LINQ to XML (是包含在我们的Silverlight 应用中的一个额外的库 )来轻松地分析和过滤从Digg返回的XML文档,使用下面的代码把它翻译成一个DiggStory对象序列:
注意上面,我们现在有了来自XML的我们可以操作的强类型的DiggStory对象。
在DataGrid控件中显示Digg故事
我们将使用新的 Silverlight DataGrid 控件来在我们的应用中显示Digg故事。要使用它,我们要引用Silverlight Data 控件程序集,然后把前面网页上的“Todo”文字替换成一个DataGrid控件声明:
查询数据部分前台界面
我们使用Silverlight2自带的DataGrid控件绑定数据。前台非常简单,只是一个DataGrid控件,但是前段时间有的同学问DataGrid控件不知怎么弄进来。这里具体说明一下。
第一步:在Silverlight工程中添加引用
第二步:查找System.Windows.Controls.Data程序集,添加进来
第三步:在UserControl中添加这个引用,有智能感知。我将其命名为Data
<UserControl x:Class="Digg.Page"
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data">
DataGrid允许你明确地配置列的声明和显示类型(为取得最大的控制),或者,你也可以设置它的AutoGenerateColumns属性成true,让DataGrid对数据源使用反射,基于你的对象的定义,为你创建默认的列。
然后我们就可以更新我们的后台代码类,用编程的方法将DataGrid的ItemSource属性绑定到在点击搜寻按钮时从Digg取回的故事序列:
现在,运行我们的Silverlight应用,做一个搜索的话,我们将看到从Digg取回的实时主题故事数据的列表:
Silverlight的Datagrid支持你预期客户端网格控件应该拥有的所有的标准功能:双向原地编辑,选择,卷动,改变表列大小等等。它还 支持自动流动的布局,意味着它可以动态地扩展或收缩来充满包含它的内容容器。DataGrid还拥有一个丰富的模板模型,允许你对显示和表列数据的编辑进 行定制。我在将来会撰写更多的贴子,讨论如何使用DataGrid。
以下的步骤
现在我们可以从Digg.com 取回Digg故事数据,并在我们的应用中将故事数据显示出来了。
下一步将是回到我们的Page.xaml 标识,去掉我们目前正在使用的行内的样式声明。