Silverlight2.0动态加载xap文件
范例来自webcast,由于版本问题,对其中代码做出了修正。简单示范在silverlight中如何动态加载xap文件。
动态加载,也就是要在运行时,加载并解析包含xap文件信息的AppManifest.xaml文件,找到合适的dll信息,通过反射机制生成silverlight相关实例。
范例来自webcast,由于版本问题,对其中代码做出了修正。简单示范在silverlight中如何动态加载xap文件。
动态加载,也就是要在运行时,加载并解析包含xap文件信息的AppManifest.xaml文件,找到合适的dll信息,通过反射机制生成silverlight相关实例。
建立项目,包括三个专案:其中DynamicXap为要动态加载的xap,TanMiLiLie为一个web应用。
此项目DynamicXap最终的标注文件AppManifest.xaml。
Code
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="DynamicXap" EntryPointType="DynamicXap.App" RuntimeVersion="2.0.31005.0">
<Deployment.Parts>
<AssemblyPart x:Name="DynamicXap" Source="DynamicXap.dll" />
<AssemblyPart x:Name="System.Windows.Controls.Data" Source="System.Windows.Controls.Data.dll" />
<AssemblyPart Source="zh-Hans/System.Windows.Controls.Data.resources.dll" />
</Deployment.Parts>
</Deployment>
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="DynamicXap" EntryPointType="DynamicXap.App" RuntimeVersion="2.0.31005.0">
<Deployment.Parts>
<AssemblyPart x:Name="DynamicXap" Source="DynamicXap.dll" />
<AssemblyPart x:Name="System.Windows.Controls.Data" Source="System.Windows.Controls.Data.dll" />
<AssemblyPart Source="zh-Hans/System.Windows.Controls.Data.resources.dll" />
</Deployment.Parts>
</Deployment>
在AssemblyPart name="DynamicXap" 的source中包含的DynamicXap.dll即是此xap文件包含的有效dll,其中包含了若干page文件,我们就是要通过解析此标注文件来生成特定的page信息。
DynamicXap中现在只包括个Page.xaml,其中的定义:
Code
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="DynamicXap.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid x:Name="dgshow" AutoGenerateColumns="True" ItemsSource="{Binding}"></data:DataGrid>
</Grid>
</UserControl>
<UserControl xmlns:data="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data" x:Class="DynamicXap.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Grid x:Name="LayoutRoot" Background="White">
<data:DataGrid x:Name="dgshow" AutoGenerateColumns="True" ItemsSource="{Binding}"></data:DataGrid>
</Grid>
</UserControl>
TanMiLiLie:在此silverlight应用动态加载上述xap文件。
Code
<UserControl x:Class="TanMiXiLie.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800" Height="700">
<Canvas Background="Khaki">
<TextBlock Canvas.Left="50" Canvas.Top="100" Text="InPut:" Foreground="Red" FontSize="20"></TextBlock>
<TextBox x:Name="txtInput" Canvas.Left="120" Canvas.Top="100" Width="150" ></TextBox>
<Button x:Name="btn" Canvas.Left="150" Canvas.Top="140" Height="30" Width="80" Content="Confirm" Click="btn_Click"></Button>
<TextBlock x:Name="txtshow" Canvas.Left="150" Canvas.Top="200" Text=""></TextBlock>
<Canvas x:Name="divshow" Canvas.Top="220" Canvas.Left="50" Height="200" Width="600" Background="White"></Canvas>
</Canvas>
</UserControl>
CodeBind:<UserControl x:Class="TanMiXiLie.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="800" Height="700">
<Canvas Background="Khaki">
<TextBlock Canvas.Left="50" Canvas.Top="100" Text="InPut:" Foreground="Red" FontSize="20"></TextBlock>
<TextBox x:Name="txtInput" Canvas.Left="120" Canvas.Top="100" Width="150" ></TextBox>
<Button x:Name="btn" Canvas.Left="150" Canvas.Top="140" Height="30" Width="80" Content="Confirm" Click="btn_Click"></Button>
<TextBlock x:Name="txtshow" Canvas.Left="150" Canvas.Top="200" Text=""></TextBlock>
<Canvas x:Name="divshow" Canvas.Top="220" Canvas.Left="50" Height="200" Width="600" Background="White"></Canvas>
</Canvas>
</UserControl>
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;
using System.IO;
using System.Windows.Resources;
using System.Windows.Markup;
using System.Xml.Linq;
namespace TanMiXiLie
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void btn_Click(object sender, RoutedEventArgs e)
{
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
//打开打包的xap文件
client.OpenReadAsync(new Uri("DynamicXap.xap", UriKind.Relative));
}
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
//解包,读取AppManifest.xaml文件信息
string appManifest = new StreamReader(Application.GetResourceStream(new StreamResourceInfo(e.Result, null), new Uri("AppManifest.xaml", UriKind.Relative)).Stream).ReadToEnd();
//------------解析AppManifest.xaml信息内容
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();
StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(e.Result, "application/binary"), new Uri(source, UriKind.Relative));
if (source == "DynamicXap.dll")
{
asm = asmPart.Load(streamInfo.Stream);
}
else
{
asmPart.Load(streamInfo.Stream);
}
}
//======================
divshow.Children.Clear();
divshow.DataContext = DataOP.getUsers(txtInput.Text);
//转换此assembly为UIElement
UIElement myData = asm.CreateInstance("DynamicXap.Page") as UIElement;
divshow.Children.Add(myData);
divshow.UpdateLayout();
}
}
}
其中涉及到的两个class的定义:using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Reflection;
using System.IO;
using System.Windows.Resources;
using System.Windows.Markup;
using System.Xml.Linq;
namespace TanMiXiLie
{
public partial class Page : UserControl
{
public Page()
{
InitializeComponent();
}
private void btn_Click(object sender, RoutedEventArgs e)
{
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
//打开打包的xap文件
client.OpenReadAsync(new Uri("DynamicXap.xap", UriKind.Relative));
}
void client_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
//解包,读取AppManifest.xaml文件信息
string appManifest = new StreamReader(Application.GetResourceStream(new StreamResourceInfo(e.Result, null), new Uri("AppManifest.xaml", UriKind.Relative)).Stream).ReadToEnd();
//------------解析AppManifest.xaml信息内容
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();
StreamResourceInfo streamInfo = Application.GetResourceStream(new StreamResourceInfo(e.Result, "application/binary"), new Uri(source, UriKind.Relative));
if (source == "DynamicXap.dll")
{
asm = asmPart.Load(streamInfo.Stream);
}
else
{
asmPart.Load(streamInfo.Stream);
}
}
//======================
divshow.Children.Clear();
divshow.DataContext = DataOP.getUsers(txtInput.Text);
//转换此assembly为UIElement
UIElement myData = asm.CreateInstance("DynamicXap.Page") as UIElement;
divshow.Children.Add(myData);
divshow.UpdateLayout();
}
}
}
Code
public class UserInfo
{
public string ID
{
set;
get;
}
public string Name
{
set;
get;
}
public string Address
{
set;
get;
}
public string Tel
{
set;
get;
}
}
public class UserInfo
{
public string ID
{
set;
get;
}
public string Name
{
set;
get;
}
public string Address
{
set;
get;
}
public string Tel
{
set;
get;
}
}
Code
public class DataOP
{
public static List<UserInfo> getUsers(string str)
{
List<UserInfo> lists=getAllUsers();
var list = from p in lists
where p.Name.ToLower().StartsWith(str)
select p;
return list.ToList();
}
private static List<UserInfo> getAllUsers()
{
List<UserInfo> lists = new List<UserInfo>()
{
new UserInfo(){ ID="1001", Name="Ivan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1002", Name="Evan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1004", Name="Bvan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1003", Name="Cvan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1005", Name="Ivan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1006", Name="Fvan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1007", Name="Ivan", Address="SZ", Tel="123456"},
};
return lists;
}
}
public class DataOP
{
public static List<UserInfo> getUsers(string str)
{
List<UserInfo> lists=getAllUsers();
var list = from p in lists
where p.Name.ToLower().StartsWith(str)
select p;
return list.ToList();
}
private static List<UserInfo> getAllUsers()
{
List<UserInfo> lists = new List<UserInfo>()
{
new UserInfo(){ ID="1001", Name="Ivan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1002", Name="Evan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1004", Name="Bvan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1003", Name="Cvan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1005", Name="Ivan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1006", Name="Fvan", Address="SZ", Tel="123456"},
new UserInfo(){ ID="1007", Name="Ivan", Address="SZ", Tel="123456"},
};
return lists;
}
}
最后运行web应用TanMiXiLieTestPage.aspx,即可看到最终效果。
注:1.其中涉及Linq to xml ,Linq to Collection的应用
2.WebClient的应用。
3.解析AppManifest.xaml时,采用linq to xml方式,避免了“Invalidoperation” 异常的出现。