65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 Silverlight 中访问外部 XAP 文件中的 UserControl

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.38/5 (3投票s)

2011年10月17日

CPOL

2分钟阅读

viewsIcon

14775

展示如何在 Silverlight 中访问外部 XAP 文件的 UserControl。

引言

众所周知,从 Silverlight 2 开始,每个项目在编译后都会被打包成 XAP 文件。访问当前 XAP 文件中的 UserControl 很容易。但是,我们如何访问外部 XAP 文件或在线 XAP 文件中的内容呢?

本文重点介绍在 Silverlight 中访问外部 XAP 文件。

背景

我们有两个 XAP 文件在服务器上:MainProject.xap,它将被添加到 MainProjectTestPagex.aspx 中作为引用,以及 ExternalProject.xap。 我们将在 MainProject.xap 中访问它的 UserControl 并显示如下

Image_1.gif

创建相关项目后,可以在 ClientBin 文件夹下找到这两个 .xap 文件。现在,我们将访问 ExternalProject.xap 的 UserControl 在 MainProject.xap 中。

然而,在实现这一点时存在两个问题

  1. ExternalProject.xap 无法下载到服务器,因为它没有页面来加载它。因此,我们需要使用编码方式进行下载。
  2. 我们需要找到相应的程序集,以便方便地进行反射访问 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);

现在,我们可以得到运行后的结果如下

Image_2.gif

此外,如果想要访问的 XAP 文件和当前 XAP 文件位于不同的网站上,我们需要添加跨域访问文件。

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>

结论

本文介绍了如何在 Silverlight 中访问外部 XAP 文件,希望对您有所帮助。

有关 Silverlight 的更多技巧,您可以访问此博客:http://janewdaisy.wordpress.com/category/silverligh/

© . All rights reserved.