概述
众所周知,在Silverlight 2开始每个项目编译后都会打包成为一个xap文件,如果我们要访问当前xap文件中的UserControl比较容易,那我们如何访问一个外部xap文件中的内容呢?甚至于如何访问一个互联网上的xap文件呢?
本文将简单介绍一下在Silverlight中如何访问外部xap文件。
需求
现在我们先来看一下需求,大致是这样子的,在服务端我们有两个xap文件,其中MainProject.xap文件将会在MainProjectTestPage.aspx中引用,而ExternalProject.xap文件中的UserControl将会在MainProject.xap文件中访问,并进行显示,如下图所示:
现在我们来建立相关的项目,最终完成的项目结构如下图所示:
分析
在实现这个过程中,我们将会遇到两个问题:
2.访问ExternalProject.xap中的UserControl,我们需要找到对应的程序集,以便使用反射,我们知道在xap文件是一个标准的zip文件,它会包含相关的程序集(接下来我会写一篇文章专门解释xap文件),如下图所示:
实现
void myButton_Click(object sender,RoutedEventArgs e) { Uri address = new Uri("http://localhost:4161/ClientBin/ExternalProject.xap"); WebClient webClient = new WebClient(); webClient.OpenReadCompleted += new OpenReadCompletedEventHandler(webClient_OpenReadCompleted); webClient.OpenReadAsync(address); } void webClient_OpenReadCompleted(object sender,OpenReadCompletedEventArgs e) { // 得到下载结果 }
这一步比较简单,接下来我们将根据下载的结果,得到相应的程序集。我们知道在xap文件中的AppManifest.xaml文件相当于一个清单,列出了当前xap文件用到的程序集(下篇文章将会介绍),它的内容如下所示:
<Deployment xmlns="[url]http://schemas.microsoft.com/client/2007/deployment[/url]" xmlns:x="[url]http://schemas.microsoft.com/winfx/2006/xaml[/url]" EntryPointAssembly="ExternalProject" EntryPointType="ExternalProject.App" RuntimeVersion="2.0.30523.6"> <Deployment.Parts> <AssemblyPart x:Name="ExternalProject" Source="ExternalProject.dll" /> </Deployment.Parts> </Deployment>
Stream stream = Application.GetResourceStream( new StreamResourceInfo(packageStream,null),new Uri("AppManifest.xaml",UriKind.Relative)).Stream; String appManifestString = new StreamReader(stream).ReadToEnd();
注意它定义了一个很重要的属性Parts,通过该属性我们就可以访问所有Deployment中的程序集。好了,现在我们看如何通过AppManifest.xaml中的内容构造Deployment对象,以及遍历其中的程序集,如下代码所示:
Deployment deployment = (Deployment)XamlReader.Load(appManifestString); Assembly assembly = null; foreach (AssemblyPart assemblyPart in deployment.Parts) { if (assemblyPart.source == assemblyName) { String source = assemblyPart.source; StreamResourceInfo streamInfo = Application.GetResourceStream( new StreamResourceInfo(packageStream,"application/binary"),new Uri(source,UriKind.Relative)); assembly = assemblyPart.Load(streamInfo.Stream); break; } } return assembly;
Assembly LoadAssemblyFromXap(Stream packageStream,String assemblyName) { Stream stream = Application.GetResourceStream( new StreamResourceInfo(packageStream,UriKind.Relative)).Stream; String appManifestString = new StreamReader(stream).ReadToEnd(); Deployment deployment = (Deployment)XamlReader.Load(appManifestString); Assembly assembly = null; foreach (AssemblyPart assemblyPart in deployment.Parts) { if (assemblyPart.source == assemblyName) { String source = assemblyPart.source; StreamResourceInfo streamInfo = Application.GetResourceStream( new StreamResourceInfo(packageStream,UriKind.Relative)); assembly = assemblyPart.Load(streamInfo.Stream); break; } } return assembly; }
Assembly assembly = LoadAssemblyFromXap(e.Result,"ExternalProject.dll"); UIElement element = assembly.CreateInstance("ExternalProject.SubPage") as UIElement; this.holder.Children.Add(element);
运行后效果如下图所示:
跨域访问
clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8"?> <access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="*" /> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access> </access-policy>
总结
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。