App.xaml Datei erhält nicht analysiert, wenn mein app keinen StartupUri gesetzt hat?
Frage
Hintergrund: Ich erstelle eine WPF-Anwendung mit MVVM und einen DI-Containern mit meinem Viewmodel bauen
Meine App.xaml sieht wie folgt aus:
<Application x:Class="WpfApp.App"
...xmlns etc...
StartupUri="MainWindow.xaml">
<Application.Resources>
<app:ServiceLocator x:Key="serviceLocator" />
</Application.Resources>
</Application>
MainWindow.xaml sieht wie folgt aus:
<Window x:Class="CompositeMefWpfApp.MainWindow"
...xmlns etc... >
<Control.DataContext>
<Binding Path="MainWindowViewModel" Source="{StaticResource serviceLocator}" />
</Control.DataContext>
Nun, dies alles funktioniert gut, aber der StartupUri
in die XAML fest einprogrammiert, die ich nicht will.
Nach Anleitung von mehreren Blogeinträge und Artikel Ich fand, entfernte ich die StartupUri
, und versuchte, die MainWindow
zu schaffen, indem OnStartup
in App.xaml.cs Einhaken, wie folgt aus:
protected override void OnStartup( StartupEventArgs e )
{
base.OnStartup(e);
new MainWindow().Show();
}
Das Problem ist, die App abstürzt, wenn man versucht, das Fenster zu zeigen, mit dieser Ausnahme:
Kann nicht Ressource mit dem Namen finden ‚{} Servicelocator‘. Ressourcennamen sind Groß- und Kleinschreibung. Fehler beim Objekt 'System.Windows.Data.Binding' in Markup-Datei 'WpfApp; Komponente / MainWindow.xaml'. Die Linie 8 Position 45
Soweit ich sagen kann, ist der <Application.Resources>
Abschnitt einfach nicht aus der XAML-Datei gelesen werden. Ich kann einige Code in der OnStartup setzen die Ressource programmatisch wie folgt hinzuzufügen:
Resources.BeginInit();
Resources.Add("serviceLocator", new ServiceLocator());
Resources.EndInit();
Doch das ist ein hässlicher Hack, und hilft mir nicht, wenn ich etwas anderes in der app.xaml Datei setzen wollte später: - (
Sollte ich ein anderes Ereignis sein Einhaken? Gibt es eine Möglichkeit, um dieses?
Lösung
Anstatt zwingende OnStartup, versuchen, ein Ereignis anstelle:
<Application x:Class="My.App"
xmlns="..."
Startup="Application_Startup"
ShutdownMode="OnExplicitShutdown">
<Application.Resources>
<app:ServiceLocator x:Key="serviceLocator" />
</Application.Resources>
</Application>
-Code hinter:
public partial class App : Application
{
public App()
{ }
private void Application_Startup(object sender, StartupEventArgs e)
{
// TODO: Parse commandline arguments and other startup work
new MainWindow().Show();
}
}
Andere Tipps
Die einfachste Abhilfe ist die Definition eines x: Name :
<Application x:Name="App" ...
<Application.Resources>
...
</Application.Resources>
</Application>
Weitere Informationen: http://connect.microsoft.com/VisualStudio/feedback/details/472729/wpf-cannot-find-resource-defined-in-the-app-xaml-file
Ich habe in ein ähnliches / das gleiche Problem führen. Es gibt eine VS Code-Generierung Bug, bei dem der Code notwendig <Application.Resources>
zum Rest des Programms verbinden manchmal nicht eingeführt wird, wenn <Application.Resources>
nur einen Eintrag enthält und kein StartupUri
Attribut.
Details: http://bengribaudo.com/blog / 2010/08/19/106 / bug-Single-application-Ressourcen-Entry-ignoriert (Disclaimer - Link verweist auf meinen Blog)
Um dieses Know Bug bekommen können Sie auch nur programmatisch Ressourcen hinzuzufügen.
var rd = new ResourceDictionary()
rd.Source = new Uri("pack://application:,,,/Resources;component/Colors.xaml");
Resources.MergedDictionaries.Add(rd);
Dieser Code kann innerhalb des construtor für die App
Klasse platziert werden.