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?

War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top