微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Silverlight 动态加载XAP文件

本文根据网上资源整理而成,主要讲述两种动态加载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,buffer.Length)) != 0)
            {
                fileStream.Write(buffer,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,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,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
            }
        }
    }
} 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐