Silverlight:利用异步加载Xap实现自定义loading效果

关键点:
1.利用WebClient的DownloadProgressChanged事件更新下载进度
2.下载完成后,分析Xap包的程序集Assembly信息

3.利用Assembly反射还原对象并加载到当前页中。

 

好处:
1.可以先定义一个简单的加载动画,吸引用户注意,避免长时间的无聊等待,改善用户体验。
2.实现按需加载,避免一次性下载过多内容。

3.在一定程度上,增加了破解难度,有助于代码保密。

Xaml :

代码

<UserControl x:Class="LoadXap.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
  <Grid x:Name="LayoutRoot">
      <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Orientation="Horizontal">
        <ProgressBar Height="15" VerticalAlignment="Center" HorizontalAlignment="Center" Width="200" x:Name="pb1" Value="0"/>
        <TextBlock x:Name="txtLoad" Text="0%" Margin="5,0,0,0"></TextBlock>
    </StackPanel>       
  </Grid>
</UserControl>

CS代码:

代码

using System;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Resources;
using System.Xml;

namespace LoadXap
{
    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();

            this.Loaded += new RoutedEventHandler(MainPage_Loaded);

        }

        void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            WebClient wc = new WebClient();
            wc.OpenReadCompleted += new OpenReadCompletedEventHandler(wc_OpenReadCompleted);
            wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
            Uri xapUri = new Uri(HtmlPage.Document.DocumentUri, "ClientBin/MainXap.xap");
            wc.OpenReadAsync(xapUri);
        }

        void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            this.txtLoad.Text = e.ProgressPercentage.ToString() + "%";
            this.pb1.Value = (double)e.ProgressPercentage;
        }

        void wc_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
        {
            Assembly assembly = GetAssemblyFromXap(e.Result, "MainXap.dll");
            UIElement element = assembly.CreateInstance("MainXap.MainPage") as UIElement;
            this.LayoutRoot.Children.Add(element);
        }

        /// <summary>
        /// 从XAP包中返回程序集信息
        /// </summary>
        /// <param name="packageStream"></param>
        /// <param name="assemblyName"></param>
        /// <returns></returns>
        private Assembly GetAssemblyFromXap(Stream packageStream, String assemblyName)
        {
            Stream stream = Application.GetResourceStream(new StreamResourceInfo(packageStream, null), new Uri("AppManifest.xaml", UriKind.Relative)).Stream;
            Assembly asm = null;
            XmlReader xmlReader = XmlReader.Create(stream);
            xmlReader.MoveToContent();
            if (xmlReader.ReadToFollowing("Deployment.Parts"))
            {
                string str = xmlReader.ReadInnerXml();
                Regex reg = new Regex("x:Name=\"(.+?)\"");
                Match match = reg.Match(str);
                string sName = "";
                if (match.Groups.Count == 2)
                {
                    sName = match.Groups[1].Value;
                }
                reg = new Regex("Source=\"(.+?)\"");
                match = reg.Match(str);
                string sSource = "";
                if (match.Groups.Count == 2)
                {
                    sSource = match.Groups[1].Value;
                }
                AssemblyPart assemblyPart = new AssemblyPart();
                StreamResourceInfo streamInfo = App.GetResourceStream(new StreamResourceInfo(packageStream, "application/binary"), new Uri(sSource, UriKind.Relative));
                if (sSource == assemblyName)
                {
                    asm = assemblyPart.Load(streamInfo.Stream);
                }
            }
            return asm;
        }
    }
}

演示效果:http://images.24city.com/jimmy/loadXap/

时间: 2024-12-03 17:57:16

Silverlight:利用异步加载Xap实现自定义loading效果的相关文章

fragment-Fragment异步加载网络数据不显示

问题描述 Fragment异步加载网络数据不显示 我一个ViewPager里有四个Fragment,然后启动应用后默认显示第一个Fragment,第一个Fragment需要从网络获取数据来设置UI的属性,所以我在第一个Fragment类中写了一个异步操作获取网络数据然后赋属性给UI,这个Fragment中还有一个按钮,点击按钮会再次从网络获取数据然后刷新UI.可是当我打开app的时候,第一个Fragment并没有显示网络数据,只有当我点击刷新按钮的时候,数据才能被显示出来.另外如果我滑动到其它几

异步加载技术实现当滚动条到最底部的瀑布流效果_php技巧

异步加载技术实现瀑布流效果.当滚动条到最底部的时候触发一个事件,这个事件写入$.get()事件,向内部程序页传递类别id和页码,程序将会返回那个类别下的相对页的产品列表,如果程序查询当前类无产品即返回空. 滚动条事件要写在window.onscroll中才有效判断.如下: window.onscroll=function(){<br> // var scrolltop=document.documentElement.scrollTop||document.body.scrollTop; va

silverlight中顺序/倒序异步加载多张图片

相册/图片切换广告等很多常用小应用中,服务器返回一组图片的uri,然后silverlight利用WebClient异步加载,如果要严格控制加载顺序的话,可以利用Stack(堆栈)或Queue(堆栈)处理,思路:不要全部一起加载,先加载第一个,在完成的异步回调过程中,继续发起一下次异步. 回想我们在ajax开发中,有一种技术叫"http长连接",在每一次ajax异步请求完成时,继续发起下一个异步请求,这样客户端与服务端的连接就一直保持下去了. 这二者多么相象!再次印证了我的那句话:技术很

利用SoftReference实现图片异步加载

//以下是mars讲解的软引用 对象存在与堆中,对象的引用存在于栈中 比如: Object obj=new Object()//obj在栈中 obj=null 当堆内存中的对象没有任何引用指向时,垃圾回收机制会回收此块内存.即当obj=null时. 软引用: 可以保证垃圾回收机制,但是同时这个引用指向块堆里的内存.所以叫软引用. 调用 Object obj=sr.get()时,假若这个对象已经被回收那么get()方法将会返回null 可以采用MAP作为缓存.缓存里存放的是键值对,键是图片的url

Android利用universal-image-loader异步加载大量图片完整示例

MainActivity如下: package cc.testlistview; import java.util.ArrayList; import com.example.testlistview.R; import com.nostra13.universalimageloader.cache.disc.naming.Md5FileNameGenerator; import com.nostra13.universalimageloader.core.ImageLoader; import

Android利用Volley异步加载数据(JSON和图片)完整示例

MainActivity如下: package cc.testvolley; import org.json.JSONObject; import android.app.Activity; import android.app.ProgressDialog; import android.graphics.Bitmap; import android.os.Bundle; import android.support.v4.util.LruCache; import android.widge

Windows Phone利用Async CTP实现异步加载数据

Async CTP是个好东西额,就是安装的时候比较坑- 跟N多补丁冲突,只要安装顺序对了才能顺利装上- 可以参考下以前写的:http://www.cnblogs.com/sun8134/archive/2011/09/19/2181030.html 异步是个好东西,可以让后台数据操作时前台也有反应而不是卡死 安装好Async CTP后,只要在wp项目中引用AsyncCtpLibrary_Phone.dll就可以使用async和await来实现异步加载了 MS已经封装好了一些异步操作,比如WebC

利用LruCache为GridView异步加载大量网络图片完整示例

MainActivity如下: package cc.testlrucache; import android.os.Bundle; import android.widget.GridView; import android.app.Activity; /** * Demo描述: * 在GridView中采用LruCache异步加载大量图片,避免OOM * * 学习资料: * http://blog.csdn.net/guolin_blog/article/details/9526203 *

解决ListView异步加载网络图片的各种问题(二)

MainActivity如下: package lee.listviewimage; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import lee.listviewimage.R; import android.app.Activity; import android.os.Bundle; import android.view.View;