Microsoft Silverlight是一个跨浏览器的、跨平台的插件,为网络带来下一代基于.NET的媒体体验和丰富的交互式应用程序。Silverlight提供灵活的编程模型,并可以很方便地集成到现有的网络应用程序中。
这里我们将讨论如何分离庞大的应用程序让用户的体验更佳:假如我们有一个5M的Silverlight程序,客户的下载速度为128Kb/s大约下载时间为40s,让用户面对silverlight默认的加载界面痴痴发呆。我在这里推荐一种动态加载的解决方案:Loader+Application+IsolatedStorage
1.首先独立创建一个Application就是我们的应用系统
2.为我们的Application创建一个精简的Loader(silverlight App),Loader的主要作用就是检查服务器端的版本和本地IsolatedStorage的版本,发现服务器新的版本则主动请求下载,否则就从IsolatedStorage读取应用程序。这样我们就可以创建丰富的加载界面(不要搞大了)。
下面附上关键代码:
WebClient client
=
new
WebClient();
client.OpenReadAsync( new Uri( string .Format( " {0}?{1} " , " Silverlight.App.xap " , DateTime.Now.Ticks), UriKind.Relative));
client.OpenReadCompleted += (o, args) =>
{
if (args.Error == null )
{
StreamResourceInfo xapResource = new StreamResourceInfo(args.Result, null );
StreamResourceInfo appManifest = Application.GetResourceStream(xapResource, new Uri( " AppManifest.xaml " , UriKind.Relative));
XmlReader xmlReader = XmlReader.Create(appManifest.Stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore });
Assembly appAssembly = null ;
List < Assembly > list = new List < Assembly > ();
while ( ! xmlReader.EOF)
{
if (xmlReader.ReadToFollowing( " AssemblyPart " ))
{
string dll = xmlReader.GetAttribute( " Source " );
StreamResourceInfo dllStreamInfo = Application.GetResourceStream(xapResource, new Uri(dll, UriKind.Relative));
AssemblyPart part = new AssemblyPart();
Assembly assembly = part.Load(dllStreamInfo.Stream);
list.Add(assembly);
}
}
appAssembly = list.SingleOrDefault((a) =>
a.FullName.StartsWith( " Silverlight.App, " )
);
if (appAssembly != null )
{
Type type = appAssembly.GetType( " Silverlight.App.MainPage " );
if (type != null )
{
UserControl control = Activator.CreateInstance(type) as UserControl;
if (control != null )
{
Panel root = (Panel)VisualTreeHelper.GetChild(App.Current.RootVisual, 0 );
root.Children.Clear();
root.Children.Add(control);
}
}
}
}
};
client.OpenReadAsync( new Uri( string .Format( " {0}?{1} " , " Silverlight.App.xap " , DateTime.Now.Ticks), UriKind.Relative));
client.OpenReadCompleted += (o, args) =>
{
if (args.Error == null )
{
StreamResourceInfo xapResource = new StreamResourceInfo(args.Result, null );
StreamResourceInfo appManifest = Application.GetResourceStream(xapResource, new Uri( " AppManifest.xaml " , UriKind.Relative));
XmlReader xmlReader = XmlReader.Create(appManifest.Stream, new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore });
Assembly appAssembly = null ;
List < Assembly > list = new List < Assembly > ();
while ( ! xmlReader.EOF)
{
if (xmlReader.ReadToFollowing( " AssemblyPart " ))
{
string dll = xmlReader.GetAttribute( " Source " );
StreamResourceInfo dllStreamInfo = Application.GetResourceStream(xapResource, new Uri(dll, UriKind.Relative));
AssemblyPart part = new AssemblyPart();
Assembly assembly = part.Load(dllStreamInfo.Stream);
list.Add(assembly);
}
}
appAssembly = list.SingleOrDefault((a) =>
a.FullName.StartsWith( " Silverlight.App, " )
);
if (appAssembly != null )
{
Type type = appAssembly.GetType( " Silverlight.App.MainPage " );
if (type != null )
{
UserControl control = Activator.CreateInstance(type) as UserControl;
if (control != null )
{
Panel root = (Panel)VisualTreeHelper.GetChild(App.Current.RootVisual, 0 );
root.Children.Clear();
root.Children.Add(control);
}
}
}
}
};
上面代码还缺少一个部分就是将目标应用程序的App资源给copy到当前App中,否则会报找不到对应资源的异常。时间紧促,后面把代码补上。
小弟献丑,欢迎各位提出宝贵的意见,大家一起讨论学习。