版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://terrylee.blog.51cto.com/342737/87094

概述

众所周知,在Silverlight 2开始每个项目编译后都会打包成为一个xap文件,如果我们要访问当前xap文件中的UserControl比较容易,那我们如何访问一个外部xap文件中的内容呢?甚至于如何访问一个互联网上的xap文件呢?
本文将简单介绍一下在Silverlight中如何访问外部xap文件。

需求

现在我们先来看一下需求,大致是这样子的,在服务端我们有两个xap文件,其中MainProject.xap文件将会在MainProjectTestPage.aspx中引用,而ExternalProject.xap文件中的UserControl将会在MainProject.xap文件中访问,并进行显示,如下图所示:
现在我们来建立相关的项目,最终完成的项目结构如下图所示:
这样在编译后,将会在ClientBin文件夹下产生两个.xap文件,现在我们将在MainProject.xap文件中访问ExternalProject.xap中的UserControl。

分析

在实现这个过程中,我们将会遇到两个问题:
1.因为没有任何页面引用ExternalProject.xap文件,所以它不会下载到客户端,这一点我们可以通过编码的方式来下载它。
2.访问ExternalProject.xap中的UserControl,我们需要找到对应的程序集,以便使用反射,我们知道在xap文件是一个标准的zip文件,它会包含相关的程序集(接下来我会写一篇文章专门解释xap文件),如下图所示:
现在解决了xap文件的下载已经程序集的访问问题,我们可以着手来实现了。

实现

实现的过程也是相当简单,首先我们使用WebClient去下载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=""xmlns:x=""EntryPointAssembly="ExternalProject"EntryPointType="ExternalProject.App"RuntimeVersion="2.0.30523.6"><Deployment.Parts><AssemblyPart x:Name="ExternalProject" Source="ExternalProject.dll" /></Deployment.Parts></Deployment>
注意,在Deployment.Parts节点下包含了当前应用程序中所有的程序集。首先要根据下载的结果获取AppManifest.xaml文件中的内容,如下代码所示:
Stream stream = Application.GetResourceStream(new StreamResourceInfo(packageStream, null),new Uri("AppManifest.xaml", UriKind.Relative)).Stream;String appManifestString = new StreamReader(stream).ReadToEnd();
有了AppManifest.xaml中内容,就可以根据它来构造一个Deployment对象,Deployment对象提供了当前应用程序的Part和本地化信息清单,它的定义如下所示:
注意它定义了一个很重要的属性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;
注意,在遍历时如果我们找到程序集名等于我们想要访问的程序集,则直接返回该程序集。最终完整的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文件不在同一站点中,需要添加跨域访问文件,如下代码所示:
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文件这一技巧,希望对大家有所帮助。示例代码下载:

本文出自 “TerryLee技术专栏” 博客,请务必保留此出处http://terrylee.blog.51cto.com/342737/87094

本文出自 51CTO.COM技术博客

转载于:https://www.cnblogs.com/hdjjun/archive/2008/12/24/1361562.html

技巧:在Silverlight中如何访问外部xap文件中UserControl相关推荐

  1. Web生产:外部JS文件中的绝对URL?

    我想知道,您是否知道在外部JavaScript文件中指定绝对URL的最佳做法? 我正在寻找一种可维护的解决方案. 基本方案是当我需要在运行时通过javascript包含css文件或对某些URL进行aj ...

  2. 外部js php变量,在外部JS文件中包含PHP变量?

    我的解决方案结合了几种技术,其中一些已经在这个问题的答案中提到过. 是的,将PHP与JS分开 首先:是的,你应该将你的JS与PHP分开.您可以将其放在单独的文件中,但是您需要对当前代码进行一些更改.不 ...

  3. maven打jar包,并将依赖jar打入外部lib文件中

    在pom.xml中加入如下配置,在mainClass里写程序的入口方法 <!-- maven打jar包,并将依赖jar打入外部lib文件中 --> <plugins> < ...

  4. 在Node.js中,如何从其他文件中“包含”函数?

    假设我有一个名为app.js的文件. 很简单: var express = require('express'); var app = express.createServer(); app.set( ...

  5. 登录plsql developer时候出现连接串问题导致的下拉列表中没有出现tnsnames.ora文件中配置的那些服务...

    问题:登录plsql developer时候出现连接串问题导致的下拉列表中没有出现tnsnames.ora文件中配置的那些服务 方法:可能是环境变量配置错了 示例 ORACLE_HOME= C:\Pr ...

  6. C# 将List中的数据导入csv文件中

    //http://www.cnblogs.com/mingmingruyuedlut/archive/2013/01/20/2849906.html C# 将List中的数据导入csv文件中 将数据保 ...

  7. 通过 crontab将linux中的top信息写入文件中

    通过 crontab将linux中的top信息写入文件中. 问题:1.直接执行命令可以正常,放到shell脚本里面执行不行.            2.直接执行shell脚本正常输出,放到cronta ...

  8. C++ 在一个cpp文件中使用另一个cpp文件中定义的函数

    C++ 在一个cpp文件中 使用另一个cpp文件中定义的函数 建立一个console项目 头文件 cpp文件 main.cpp 建立一个console项目 以dev为例,在[文件][新建][项目],新 ...

  9. python 在一个py文件中调用另一个py文件中的变量以及一个有趣的问题

    python 在一个py文件中调用另一个py文件中的变量以及一个有趣的问题 1.在一个py文件中调用另一个py文件中的变量 新建一个py文件,记为t1.py # t1.py m = 2 n = 1 a ...

最新文章

  1. AGX Xavier CAN调试
  2. python 內建数据类型
  3. [JAVA]引入目录下所有jar包等问题
  4. hibernate查询之条件查询
  5. Python 字符串转义序列及格式化
  6. 只需要30秒就可以做的30件事情:你会选择哪一件来改变世界?
  7. python中输入17=x会引起错误_python新手常犯的17个错误
  8. brew安装指定版本mysql,Mac 系统为 Valet 开发环境安装指定版本 MySQL
  9. JavaScript的类型自动转换高级玩法JSFuck
  10. Ubuntu-安装MySQL5.7并配置用户名密码
  11. CentOS[linux]操作系统的安装手册
  12. Excel常用技巧大全
  13. deepinV20 显卡驱动 cuda10.2+cudnn配置
  14. PHP如何启动scrapy,python,_新手Scrapy爬虫运行问题,python - phpStudy
  15. 赠书:支付平台架构业务、规划、设计与实现
  16. 用python制作音乐_Python3使用PySynth制作音乐的方法
  17. 项目构建工具--webpack
  18. 由sizeof 这个“管”,窥一窥C语言这只“豹”
  19. ai电话机器人销售过程自动化功能,黑斑马电话机器人系统
  20. windows批处理命令:创建文件并写入内容的bat脚本

热门文章

  1. 推荐asp.net调试工具:miniASPNETServer
  2. 算法题存档2020425
  3. golang利用json.Unmarshal转json为map、slice类型
  4. MySQL高并发事务问题
  5. 线上频繁发生Full GC 如何调优?如何快速定位OOM、cpu飙升、线程死锁等问题
  6. oracle 自动表分析,其实 Oracle 直方图自动统计算法存在这些缺陷!
  7. android 脚本录制工具,[atx 系列] android 脚本录制
  8. 总结了一下初学者对Go错误处理的四个误解!
  9. 中秋节,给大家送点货真价实的礼物
  10. jenkins集成gitlab