App.xaml di file non viene analizzata se la mia applicazione non imposta uno StartupUri?

StackOverflow https://stackoverflow.com/questions/543414

  •  23-08-2019
  •  | 
  •  

Domanda

Background: Sto creando un'applicazione WPF utilizzando MVVM, e l'utilizzo di un contenitore DI costruire i miei ViewModels

Il mio App.xaml si presenta così:

<Application x:Class="WpfApp.App"
    ...xmlns etc...
    StartupUri="MainWindow.xaml">
    <Application.Resources>
        <app:ServiceLocator x:Key="serviceLocator" />
    </Application.Resources>
</Application>

MainWindow.xaml assomiglia a questo:

<Window x:Class="CompositeMefWpfApp.MainWindow"
    ...xmlns etc... >
    <Control.DataContext>
        <Binding Path="MainWindowViewModel" Source="{StaticResource serviceLocator}" />
    </Control.DataContext>

Ora, tutto questo funziona benissimo, ma il StartupUri è insita nel XAML, che io non voglio.
Seguendo la guida di diversi blogposts e articoli che ho trovato, ho rimosso il StartupUri, e ho cercato di creare il MainWindow agganciando OnStartup in App.xaml.cs, in questo modo:

protected override void OnStartup( StartupEventArgs e )
{
    base.OnStartup(e);
    new MainWindow().Show();
}

Il problema è che l'applicazione si blocca quando si tenta di visualizzare la finestra, con questa eccezione:

  

Non riesci a trovare risorse denominato '{} ServiceLocator'. i nomi delle risorse sono case sensitive. Errore in oggetto 'System.Windows.Data.Binding' nel file di markup 'WpfApp; component / MainWindow.xaml'. Linea 8 Posizione 45

Per quanto posso dire, la sezione <Application.Resources> è semplicemente non vengono letti dal file XAML. Posso mettere un po 'di codice nel OnStartup per aggiungere la risorsa programatically in questo modo:

Resources.BeginInit();
Resources.Add("serviceLocator", new ServiceLocator());
Resources.EndInit();

Tuttavia questo è un brutto hack, e non mi aiuta se ho voluto mettere qualcosa di diverso nel file App.xaml seguito: - (

Dovrei conquistano gli qualche altro evento? C'è un modo per aggirare questo?

È stato utile?

Soluzione

Piuttosto che sovrascrivendo OnStartup, provare a utilizzare un evento invece:

<Application x:Class="My.App"
    xmlns="..."
    Startup="Application_Startup"
    ShutdownMode="OnExplicitShutdown">
        <Application.Resources>
            <app:ServiceLocator x:Key="serviceLocator" />
        </Application.Resources>
    </Application>

Codice dietro:

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();
    }
}

Altri suggerimenti

La soluzione più semplice è la definizione di un x: Nome :

<Application x:Name="App" ...
    <Application.Resources>
        ...
    </Application.Resources>
</Application>

Più informazioni: http://connect.microsoft.com/VisualStudio/feedback/details/472729/wpf-cannot-find-resource-defined-in-the-app-xaml-file

Ho eseguito in un / questo stesso problema simile. C'è un VS generazione di codice bug in cui il codice necessario per collegare <Application.Resources> al resto del programma a volte non è inserito quando <Application.Resources> contiene una sola voce e non dispone di un attributo StartupUri.

Dettagli: http://bengribaudo.com/blog / 2010/08/19/106 / bug-single-application-risorse-entry-ignorato (disclaimer - collegamento punti al mio blog)

Per ovviare a questo problema sapere che si può anche solo aggiungere risorse a livello di codice.

var rd = new ResourceDictionary()
rd.Source = new Uri("pack://application:,,,/Resources;component/Colors.xaml");
Resources.MergedDictionaries.Add(rd);

Questo codice può essere collocato all'interno del construtor per la classe App.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top