Introduction
As is known, every project will be packed as a XAP file after compiling from Silverlight 2. It is easy to visit a UserControl in the current XAP file.
However, how do we visit contents of an external XAP file or XAP files online?
This article focuses on visiting an external XAP file in Silverlight.
Background
We have two XAP files on server: MainProject.xap, which will be added as a reference in MainProjectTestPagex.aspx, and ExternalProject.xap.
We will visit its UserControl in MainProject.xap and display as follows:
After creating the related project, we can find the two .xap files under the ClientBin folder. Now we will visit the UserControl of ExternalProject.xap
in MainProject.xap.
However, there are two problems when realizing this:
- ExternalProject.xap cannot be downloaded to the server because there is no page to load it. So we need to download with encoding.
- We need to find the corresponding assembly to be convenient for reflecting to visit ExternalProject.xap.
After solving the two problems, we can start to realize the visitation.
Using the code
Firstly, we need to download the XAP file by using a WebClient
.
void myButton_Click(object sender, RoutedEventArgs e)
{
Uri address = new Uri("http://localhost:4161/ClientBin/ExternalProject.xap");
WebClient webClient = new WebClient();
webClient.OpenReadCompleted +=
new OpenReadCompletedEventHandler(webClient_OpenReadCompleted);
webClient.OpenReadAsync(address);
}
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
Get Download Result
}
Then we can get the corresponding assembly according to the download result. As we know, the AppManifest.xaml file in the XAP file is like a list, which shows the assembly
the current XAP file will use. Its content is shown here:
<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: if we find the assembly which we want when traversing, return this assembly directly.
The following listing shows the complete LoadAssemblyFromXap
method:
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 getting the assembly, we use Reflection to create a related instance and loading on the page.
Assembly assembly = LoadAssemblyFromXap(e.Result, "ExternalProject.dll");
UIElement element = assembly.CreateInstance("ExternalProject.SubPage") as UIElement;
this.holder.Children.Add(element);
Now, we can get the result after running as follows:
What's more, if the XAP file which you want to visit and the current XAP file are in different websites, we need to add the cross domain access file.
clientaccesspolicy.xml:
="1.0" ="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>
Conclusion
This article explains how to visit an external XAP file in Silverlight and I hope that it will be helpful for you.
For more tips on Silverlight, you can visit this blog: http://janewdaisy.wordpress.com/category/silverligh/.