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/




你可能感兴趣的:(silverlight)