2009-02-12 10 views
34

Antecedentes: Estoy creando una aplicación de WPF usando MVVM, y el uso de un contenedor DI para construir mis ViewModelsEl archivo App.xaml no se analiza si mi aplicación no configura un StartupUri?

Mi App.xaml se ve así:

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

MainWindow.xaml se ve así:

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

Ahora, todo funciona bien, pero el StartupUri está codificado en el XAML, que no quiero.
Siguiendo la orientación de varias entradas del blog y artículos que he encontrado, he quitado el StartupUri, y trataron de crear la MainWindow enganchando OnStartup en App.xaml.cs, así:

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

El problema es, la aplicación se bloquea cuando intenta mostrar la ventana, con esta excepción:

No se encuentra el recurso llamado '{serviceLocator}'. Los nombres de los recursos son sensibles a las mayúsculas Error en el objeto 'System.Windows.Data.Binding' en el archivo de anotación 'WpfApp; componente/MainWindow.xaml' Línea 8 Posición 45.

Por lo que yo puedo decir, simplemente no está siendo leído la sección <Application.Resources> fuera del archivo xaml. Puedo poner un poco de código en el OnStartup añadir el recurso programáticamente como esto:

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

Sin embargo eso es un truco feo, y no me ayuda si quería poner algo más en el archivo App.xaml más adelante ? :-(

¿Debo de enganche algún otro evento ¿hay una forma de evitar esto

Respuesta

38

lugar de sustituir OnStartup, intente utilizar un evento en su lugar:?

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

detrás del código:

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

Esto lo resuelve, gracias! –

+1

¡Dios mío, gracias! Pensé que me estaba volviendo loco – Heliac

+1

¿Por qué es importante configurar el evento desde xaml? Falla si se configura desde el constructor ... –

12

Me he encontrado con un similar/este mismo problema. Hay un error de generación de código VS donde el código necesario para conectar <Application.Resources> al resto del programa a veces no se inserta cuando <Application.Resources> contiene solo una entrada y no tiene un atributo StartupUri.

Detalles: http://bengribaudo.com/blog/2010/08/19/106/bug-single-application-resources-entry-ignored(disclaimer - enlace apunta a mi blog)

+2

Visual Studio 2012 con .NET Framework 4.5 Todavía tiene un error – Lu55

+0

Visual Studio 2015 todavía tiene el error :-(Pasaron otras tres horas de mi vida. –

17

La más sencilla solución es la definición de un x: Nombre:

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

Más información: http://connect.microsoft.com/VisualStudio/feedback/details/472729/wpf-cannot-find-resource-defined-in-the-app-xaml-file

+0

el enlace está roto No se puede encontrar el problema a través de la búsqueda – Lu55

+0

Se agregó una nueva https://connect.microsoft.com/VisualStudio/feedback/details/772087/ – Lu55

+0

Esta solución me ha funcionado y es la más simple. – bignermo

1

Para evitar este error conocido también puede agregar recursos programáticamente.

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

Este código se puede colocar dentro del construtor para la clase App.

Cuestiones relacionadas