Ich weiß, dass es möglich ist, XAP-Module dynamisch mit Prism oder MEF-Framework zu laden. Allerdings möchte ich diese Frameworks nicht verwenden; Laden Sie stattdessen meine xap-Dateien manuell. Also, ich habe die folgende Klasse (aus dem Internet) erstellt:silverlight 4, dynamisch laden xap-Module
public class XapLoader
{
public event XapLoadedEventHandler Completed;
private string _xapName;
public XapLoader(string xapName)
{
if (string.IsNullOrWhiteSpace(xapName))
throw new ArgumentException("Invalid module name!");
else
_xapName = xapName;
}
public void Begin()
{
Uri uri = new Uri(_xapName, UriKind.Relative);
if (uri != null)
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += onXapLoadingResponse;
wc.OpenReadAsync(uri);
}
}
private void onXapLoadingResponse(object sender, OpenReadCompletedEventArgs e)
{
if ((e.Error == null) && (e.Cancelled == false))
initXap(e.Result);
if (Completed != null)
{
XapLoadedEventArgs args = new XapLoadedEventArgs();
args.Error = e.Error;
args.Cancelled = e.Cancelled;
Completed(this, args);
}
}
private void initXap(Stream stream)
{
string appManifest = new StreamReader(Application.GetResourceStream(
new StreamResourceInfo(stream, null), new Uri("AppManifest.xaml",
UriKind.Relative)).Stream).ReadToEnd();
XElement deploy = XDocument.Parse(appManifest).Root;
List<XElement> parts = (from assemblyParts in deploy.Elements().Elements()
select assemblyParts).ToList();
foreach (XElement xe in parts)
{
string source = xe.Attribute("Source").Value;
AssemblyPart asmPart = new AssemblyPart();
StreamResourceInfo streamInfo = Application.GetResourceStream(
new StreamResourceInfo(stream, "application/binary"),
new Uri(source, UriKind.Relative));
asmPart.Load(streamInfo.Stream);
}
}
}
public delegate void XapLoadedEventHandler(object sender, XapLoadedEventArgs e);
public class XapLoadedEventArgs : EventArgs
{
public Exception Error { get; set; }
public bool Cancelled { get; set; }
}
Der obige Code funktioniert gut; Ich kann jede xap die folgende Art und Weise laden:
XapLoader xapLoader = new XapLoader("Sales.xap");
xapLoader.Completed += new XapLoadedEventHandler(xapLoader_Completed);
xapLoader.Begin();
Nun, ich habe einen Usercontrol InvoiceView im Sales.xap Projekt genannt, so mag ich die Klasse instanziiert. Im aktuellen Projekt (Main.xap) habe ich einen Verweis auf das Sales.xap-Projekt hinzugefügt, da ich es jedoch manuell lade, setze ich "Copy Local = False". Aber wenn sie ausgeführt werden, wirft der folgende Code Type:
Sales.InvoiceView view = new Sales.InvoiceView();
Es scheint, den Code nicht InvoiceView Klasse finden. Aber ich habe überprüft, dass die initXap() -Methode von XapLoader erfolgreich ausgeführt wurde. Warum kann der Code die InvoiceView-Klasse nicht finden? Kann mir jemand bei diesem Problem helfen?
Eine einfachere Möglichkeit, dies zu tun, ist die Verwendung des Managed Extensibility Framework (MEF), das in Silverlight 4 zusätzlich zu .NET 4 integriert ist. –