zoukankan      html  css  js  c++  java
  • 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/




    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    [商业][思想]《免费 商业的未来 Free The Future of a Radical Price》 克里斯·安德森(美)
    《幸福就在你身边》第六课、心动就要行动【哈佛大学"幸福课"精华】
    人性歪曲的心理调适 一【犹豫心理、怯场心理、依赖心理、盲从心理、攀比心理】
    《幸福就在你身边》第九课、确信自己有好命【哈佛大学"幸福课"精华】
    ORACLE FLASHBACK恢复删除的所有表
    抽象类和接口的例子
    抽象类专题二:抽象类的用途
    Entity Framework中的批量提交与事务处理[转]
    如何处理JSON中的特殊字符
    C# params参数的应用
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1629947.html
Copyright © 2011-2022 走看看