Silverlight 动态加载XAP文件

来源:互联网 发布:11选5遗漏数据 编辑:程序博客网 时间:2024/04/29 05:58

本文根据网上资源整理而成,主要讲述两种动态加载Silverlight生成后的XAP文件的方法,实现按需下载减小传输文件的目的。
前置说明:

本文例子用VS2012编写,解决方案中有三个项目,一个Web应用程序,两个Silverlight应用程序(不是类库,类库在生成时默认不会生成独立的XAP包),如下图


1、方法一,直接将需要的XAP文件下载到本地内存
说明:这种方式,每次从服务器获得的XAP文件都是最新的,如果服务器端的XAP文件有所更改,客户端也会马上显示出来

根据例子来讲解,SlLogin.xap是程序运行时默认加载的XAP文件,SilverlightPartXap.xap是点击SlLogin项目中Login页面上的登录按钮后加载的XAP文件,并将新加载的XAP文件中的UI界面显示出来,Login.xaml后台主要源码如下(Login.cs):

using System;using System.Collections.Generic;using System.IO;using System.Linq;using System.Net;using System.Reflection;using System.Windows;using System.Windows.Controls;using System.Windows.Resources;using System.Xml.Linq;namespace SlLogin{    public partial class MainPage : UserControl    {        public MainPage()        {            InitializeComponent();        }        //登录        private void btnLogin_Click(object sender, RoutedEventArgs e)        {            Uri mainXapUri = new Uri("SilverlightPartXap.xap",UriKind.Relative);            WebClient webClient = new WebClient();            webClient.OpenReadCompleted += webClient_OpenReadCompleted;            webClient.OpenReadAsync(mainXapUri);//获取另一个xap文件        }        void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)        {            Stream mainXapStream = e.Result;            Assembly mainAssembly = LoadAssemblyFromXap(mainXapStream, "SilverlightPartXap.dll");            UIElement mainFrame = mainAssembly.CreateInstance("SilverlightPartXap.MainPage") as UIElement;            this.Content = mainFrame;        }        /// <summary>        /// 从XAP中获取程序集        /// </summary>        /// <param name="packageStream"></param>        /// <param name="assemblyName"></param>        /// <returns></returns>        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();            //Linq to xml            XElement deploymentRoot = XDocument.Parse(appManifestString).Root;            List<XElement> deploymentParts = (from assemblyParts in deploymentRoot.Elements().Elements()                                              select assemblyParts).ToList();            Assembly asm = null;            foreach (XElement xElement in deploymentParts)            {                string source = xElement.Attribute("Source").Value;                AssemblyPart asmPart = new AssemblyPart();                asmPart.Source = source;                StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(packageStream, "application/binary"), new Uri(source, UriKind.Relative));                if (source == "SilverlightPartXap.dll")                {                    asm = asmPart.Load(streamInfo.Stream);                }                else                {                    asmPart.Load(streamInfo.Stream);                }            }            return asm;        }    }}


 

2.方法二,使用silverlight的独立存储区来存放从服务器动态加载的XAP文件,这样只要独立存储区的内容还存在,它就会使用独立存储区的内容,而不去从服务器重新加载,但得不到新的XAP,一旦服务器的XAP修改了,也不会立马显示,源码如下:

using System;using System.Collections.Generic;using System.IO;using System.IO.IsolatedStorage;using System.Linq;using System.Net;using System.Reflection;using System.Windows;using System.Windows.Controls;using System.Windows.Resources;using System.Xml.Linq;namespace SlLogin{    public partial class NLogin : UserControl    {        public NLogin()        {            InitializeComponent();        }        //登录        private void btnLogin_Click(object sender, RoutedEventArgs e)        {            using (var store = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())            {                if (!store.FileExists("SilverlightPartXap.xap"))                {                    WebClient c = new WebClient();                    c.OpenReadCompleted += new OpenReadCompletedEventHandler(c_OpenReadCompleted);                    c.OpenReadAsync(new Uri("SilverlightPartXap.xap", UriKind.Relative));                }                else                {                    LoadData();                }            }        }        void c_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)        {            using (var store = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())            {                System.IO.IsolatedStorage.IsolatedStorageFileStream fileStream;                // create the file                  fileStream = store.CreateFile("SilverlightPartXap.xap");                // write out the stream to isostore                 WriteStream(e.Result, fileStream);                fileStream.Close();            }            LoadData();        }        private void WriteStream(Stream stream, System.IO.IsolatedStorage.IsolatedStorageFileStream fileStream)        {            byte[] buffer = new byte[4096];            int bytesRead;            while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)            {                fileStream.Write(buffer, 0, bytesRead);            }        }        private void LoadData()        {            using (var store = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())            {                IsolatedStorageFileStream fileStream = store.OpenFile("SilverlightPartXap.xap", FileMode.Open, FileAccess.Read);                #region Original Code                StreamResourceInfo sri = new StreamResourceInfo(fileStream, "application/binary");                Stream manifestStream = Application.GetResourceStream(sri, new Uri("AppManifest.xaml", UriKind.Relative)).Stream;                string appManifest = new StreamReader(manifestStream).ReadToEnd();                //Linq to xml                XElement deploymentRoot = XDocument.Parse(appManifest).Root;                List<XElement> deploymentParts = (from assemblyParts in deploymentRoot.Elements().Elements()                                                  select assemblyParts).ToList();                Assembly asm = null;                foreach (XElement xElement in deploymentParts)                {                    string source = xElement.Attribute("Source").Value;                    AssemblyPart asmPart = new AssemblyPart();                    asmPart.Source = source;                    StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(fileStream, "application/binary"), new Uri(source, UriKind.Relative));                    if (source == "SilverlightPartXap.dll")                    {                        asm = asmPart.Load(streamInfo.Stream);                    }                    else                    {                        asmPart.Load(streamInfo.Stream);                    }                }                UIElement myData = asm.CreateInstance("SilverlightPartXap.MainPage") as UIElement;                this.Content = myData;                #endregion            }        }    }} 
原创粉丝点击