WebClient 类提供了下载应用程序数据(如 XAML 内容)、附加程序集或媒体资产(如图像)的功能。WebClient 类可以根据应用程序需要按需下载内容。您可以以异步方式显示或使用下载的内容。这意味着您不必刷新包含 Silverlight 控件的 HTML 页,即使您更换 HTML 页上的大多数 Silverlight 内容也不例外。WebClient 类提供了用于启动下载请求、监视请求进度和检索已下载内容的功能。例如,如果应用程序在初始应用程序加载后立即从视频库播放视频,则您可能选择了开始请求库中的每个视频。这意味着视频可用于浏览器缓存,并且可以在渐进式下载(而不是对视频进行流处理)之后在本地进行播放,这可能导致用户可见的缓冲间隙。
WebClient 请求是异步的,因此,代码与 WebClient 之间的大多数交互将通过事件处理程序来实现。通常,这涉及到为以下一个或多个事件定义事件处理程序:
当您启动请求时,您可以使用不同的 WebClient 类方法,具体取决于您是作为流还是作为字符串来请求资源。
若要请求作为流来读取资源,请首先调用 OpenReadAsync 的以下重载之一:
OpenReadAsync(Uri, Object)
接下来,处理 OpenReadCompleted 事件。
若要请求作为字符串来下载资源,请调用 DownloadStringAsync 的以下重载之一:
-
DownloadStringAsync(Uri, Object)
接下来,处理 DownloadStringCompleted 事件。
下载包
Silverlight 提供将内容作为包下载的能力,包是独立文件的集合,这些独立文件包含 XAML 内容、媒体资产和其他应用程序数据。如果您正在下载包,则调用 OpenReadAsync,以便返回的类型为 Stream。
从包中获得指定的部分不是直接通过 WebClient 类来完成的。而是使用 StreamResourceInfo 将流作为包进行处理,然后将包的其中一个部分作为新流返回。
使用 SetSource 方法
一些媒体类型可能以异步方式设置其源属性。首先获取包含前面介绍的源材料的特定流。然后,调用将流用作对象媒体源的方法之一。下面是以此方式工作的方法的列表:
SetSource 可用作 Image..::..Source 或 ImageBrush..::..ImageSource 的公共源。这就为 Image 或 ImageBrush 启用了异步源设置。
还可以为 VideoBrush 设置异步源。首先,应为用作 SetSource 的视频源的 MediaElement 设置源。然后,调用 SetSource。
例如,某个包可能包含一个用于 Image 源的图形文件。在这种情况下,part 引用是包中单独内容的文件名。
下面的 C# 示例演示如何使用 SetSource 方法通过已下载内容中的特定部分流来填充 ImageSource。然后,使用 ImageSource 设置 Image 对象的 Source 属性。
第一个代码实例为请求建立 WebClient,添加完成的处理程序并启动请求。请注意,它传递标记值 imgPart。这将通知处理程序您需要整个包中的哪个部分。
void DownloadImagePart(string imgPart)
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
wc.OpenReadAsync(new Uri("imgs.zip", UriKind.Relative), imgPart);
}
接下来的代码示例定义在先前代码中引用的已完成的处理程序。在已完成的处理程序中,将处理初始流以获取特定部分,然后使用该部分来设置图像源。部分名称本身作为标记传递,从 e.UserState 中检索并用于在流/包内指定 URI。此代码示例中的 ImgToFill 是对于 Image 的引用,后者是使用 ImgToFill(未显示)的 x:Name 在 XAML 中定义的。
void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
StreamResourceInfo sri = new StreamResourceInfo(e.Result as Stream, null);
String sURI = e.UserState as String;
StreamResourceInfo imageStream = Application.GetResourceStream(sri, new Uri(sURI, UriKind.Relative));
BitmapSource imgsrc = new BitmapSource ();
imgsrc.SetSource(imageStream.Stream);
ImgToFill.Source = imgsrc;
}