如何在 Silverlight 中访问外部 XAP 文件中的 UserControl
展示如何在 Silverlight 中访问外部 XAP 文件的 UserControl。
引言
众所周知,从 Silverlight 2 开始,每个项目在编译后都会被打包成 XAP 文件。访问当前 XAP 文件中的 UserControl 很容易。但是,我们如何访问外部 XAP 文件或在线 XAP 文件中的内容呢?
本文重点介绍在 Silverlight 中访问外部 XAP 文件。
背景
我们有两个 XAP 文件在服务器上:MainProject.xap,它将被添加到 MainProjectTestPagex.aspx 中作为引用,以及 ExternalProject.xap。 我们将在 MainProject.xap 中访问它的 UserControl 并显示如下
创建相关项目后,可以在 ClientBin 文件夹下找到这两个 .xap 文件。现在,我们将访问 ExternalProject.xap 的 UserControl 在 MainProject.xap 中。
然而,在实现这一点时存在两个问题
- ExternalProject.xap 无法下载到服务器,因为它没有页面来加载它。因此,我们需要使用编码方式进行下载。
- 我们需要找到相应的程序集,以便方便地进行反射访问 ExternalProject.xap。
解决这两个问题后,我们就可以开始实现访问了。
使用代码
首先,我们需要使用 WebClient
下载 XAP 文件。
void myButton_Click(object sender, RoutedEventArgs e)
{
Uri address = new Uri("https://:4161/ClientBin/ExternalProject.xap");
WebClient webClient = new WebClient();
webClient.OpenReadCompleted +=
new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(address);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
//
Get Download Result
}
然后,我们可以根据下载结果获取相应的程序集。如我们所知,XAP 文件中的 AppManifest.xaml 文件就像一个列表,显示当前 XAP 文件将使用的程序集。其内容如下所示
<Deployment
xmlns="http://schemas.microsoft.com/client/2007/deployment"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
EntryPointAssembly="ExternalProject"
EntryPointType="ExternalProject.App"
RuntimeVersion="2.0.30523.6">
<Deployment.Parts>
<AssemblyPart x:Name="ExternalProject" Source="ExternalProject.dll" />
</Deployment.Parts>
</Deployment>
注意:如果在遍历时找到我们想要的程序集,则直接返回该程序集。
以下代码段显示了完整的 LoadAssemblyFromXap
方法
Assembly LoadAssemblyFromXap(Stream packageStream,String assemblyName)
{
Stream stream = Application.GetResourceStream(
new StreamResourceInfo(packageStream, null),
new Uri("AppManifest.xaml", 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,
"application/binary"),
new Uri(source,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);
现在,我们可以得到运行后的结果如下
此外,如果想要访问的 XAP 文件和当前 XAP 文件位于不同的网站上,我们需要添加跨域访问文件。
<?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>
结论
本文介绍了如何在 Silverlight 中访问外部 XAP 文件,希望对您有所帮助。
有关 Silverlight 的更多技巧,您可以访问此博客:http://janewdaisy.wordpress.com/category/silverligh/。