Overview
As we all know, each project is packaged into an xap file after being compiled in Silverlight 2. It is easier to access the usercontrol in the current xap file, how can we access the content in an external xap file? How can I access an xap file on the Internet?
This article briefly introduces how to access external xap files in Silverlight.
Requirement
Now let's take a look at the requirements. Generally, we have two xap files on the server, mainproject. the xap file will be in mainprojecttestpage. aspx references, while externalproject. the usercontrol in the xap file will be in the mainproject. access and display in the xap file, as shown in:
Now let's create related projects. The final project structure is shown in:
After compilation, two. xap files will be generated in the clientbin folder. Now we will access usercontrol in externalproject. xap in the mainproject. xap file.
Analysis
In this process, we will encounter two problems:
1. Because there is no page to reference the externalproject. xap file, it will not be downloaded to the client. We can download it by encoding.
2. access externalproject. in xap, we need to find the corresponding Assembly to use reflection. We know that the xap file is a standard ZIP file, it will contain the relevant Assembly (next I will write an article specifically explaining the xap file), as shown in:
Now we have solved the problem of accessing the xap file by downloading the Assembly. We can proceed with the implementation.
Implementation
The implementation process is quite simple. First, we use WebClient to download xap files. I believe everyone knows what to do, as shown in the following code.
Void mybutton_click (Object sender, routedeventargs e) {URI address = new uri ("http: // localhost: 4161/clientbin/externalproject. xap "); WebClient = new WebClient (); WebClient. openreadcompleted + = new openreadcompletedeventhandler (webclient_openreadcompleted); WebClient. openreadasync (Address);} void webclient_openreadcompleted (Object sender, openreadcompletedeventargs e) {// get the download result}
This step is relatively simple. Next we will get the corresponding Assembly Based on the download results. We know that the appmanifest. XAML file in the xap file is equivalent to a list that lists the Assembly used by the current xap file (which will be introduced in the next article). Its content is as follows:
<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="ExternalProject" EntryPointType="ExternalProject.App" RuntimeVersion="2.0.30523.6"> <Deployment.Parts> <AssemblyPart x:Name="ExternalProject" Source="ExternalProject.dll" /> </Deployment.Parts></Deployment>
Note that the deployment. Parts node contains all the assemblies of the current application. First, obtain the content in the appmanifest. XAML File Based on the download result, as shown in the following code:
Stream stream = Application.GetResourceStream( new StreamResourceInfo(packageStream, null), new Uri("AppManifest.xaml", UriKind.Relative)).Stream;String appManifestString = new StreamReader(stream).ReadToEnd();
With the content in appmanifest. XAML, You can construct a deployment object based on it. The deployment object provides the part and localization information list of the current application. Its definition is as follows:
Note that it defines a very important attribute parts, through which we can access the Assembly in all deployment. Now we can see how to construct a deployment object through the content in appmanifest. XAML and traverse the Assembly, as shown in the following code:
Deployment deployment = (Deployment)XamlReader.Load(appManifestString);Assembly assembly = null;foreach (AssemblyPart assemblyPart in deployment.Parts){ if (assemblyPart.Source == assemblyName) { String source = assemblyPart.Source; StreamResourceInfo streamInfo = Application.GetResourceStream( new StreamResourceInfo(packageStream, "application/binary"), new Uri(source,UriKind.Relative)); assembly = assemblyPart.Load(streamInfo.Stream); break; }}return assembly;
NOTE: If we find the Assembly whose name is equal to the one we want to access during the traversal, the Assembly will be directly returned. The complete loadassemblyfromxap method code is as follows:
Assembly LoadAssemblyFromXap(Stream packageStream,String assemblyName){ Stream stream = Application.GetResourceStream( new StreamResourceInfo(packageStream, null), new Uri("AppManifest.xaml", UriKind.Relative)).Stream; String appManifestString = new StreamReader(stream).ReadToEnd(); Deployment deployment = (Deployment)XamlReader.Load(appManifestString); Assembly assembly = null; foreach (AssemblyPart assemblyPart in deployment.Parts) { if (assemblyPart.Source == assemblyName) { String source = assemblyPart.Source; StreamResourceInfo streamInfo = Application.GetResourceStream( new StreamResourceInfo(packageStream, "application/binary"), new Uri(source,UriKind.Relative)); assembly = assemblyPart.Load(streamInfo.Stream); break; } } return assembly;}
After obtaining the Assembly, use reflection to create related instances and load them on the page, as shown in the following code:
Assembly assembly = LoadAssemblyFromXap(e.Result, "ExternalProject.dll");UIElement element = assembly.CreateInstance("ExternalProject.SubPage") as UIElement;this.holder.Children.Add(element);
Shows the effect after running:
Cross-origin access
In the preceding example, cross-origin is not involved (I will write a special article to introduce). If the xap file you want to access is not in the same site as the current xap file, the following code adds a cross-origin access file:
Clientaccesspolicy. xml:
<?xml version="1.0" encoding="utf-8"?><access-policy> <cross-domain-access> <policy> <allow-from http-request-headers="*" /> <domain uri="*"/> </allow-from> <grant-to> <resource path="/" include-subpaths="true"/> </grant-to> </policy> </cross-domain-access></access-policy>
Summary
This article describes how to access external xap files in Silverlight.
From: http://kb.cnblogs.com/kb/42899/
There is another experience: http://www.soaspx.com/dotnet/silverlight/silverlight_20100124_2551.html