Может быть, я делаю это действительно очень сложным способом, но я обнаружил, что бороться с приоритетом / порядком вызова при запуске, предполагая, что что-то бесполезно. Я действительно хотел, чтобы любое исключение, возникающее во время запуска приложения, мгновенно всплывало до самого внешнего обработчика исключений, но даже когда оно было вызвано, мой объект локатора MVVM автоматически создавался, поскольку он определен как ресурс уровня приложения.
Это означало, что курица прибыла до яйца, но после того, как то же яйцо уже сломалось !!!
Итак, решение было:
1) Удалить локатор MVVM из файла App.xaml.
2) Создать событие Application_Startup
Добавьте эти строки вверху:
#region Handlers For Unhandled Exceptions
// anything else to do on startup can go here and will fire after the base startup event of the application
// First make sure anything after this is handled
// Creates an instance of the class holding delegate methods that will handle unhandled exceptions.
CustomExceptionHandler eh = new CustomExceptionHandler();
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(eh.OnAppDomainException);
// this ensures that any unhandled exceptions bubble up to a messagebox at least
Dispatcher.CurrentDispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(eh.OnDispatcherUnhandledException);
#endregion Handlers For Unhandled Exceptions
3) Свяжите запуск с событием Application_Startup в App.xaml
например, * 1 016 *
Startup="Application_Startup" <<<< this name is arbitrary but conventional AFAICT
4) В Applicaton_Startup создайте ViewModelLocator следующим образом:
Resources.Add("Locator", new ViewModelLocator());
//You can use FindResource and an exception will be thrown straightaway as I recall
if (!(TryFindResource("Locator") == null))
throw new ResourceReferenceKeyNotFoundException("ViewModelLocator could not be created", "Locator");
5) Затем, сразу после того, как ресурс был найден, откройте MainWindow, но только если экземпляр локатора был успешно создан
Uri uri = new Uri("pack:Views/MainWindow.xaml", UriKind.RelativeOrAbsolute);
Application.Current.StartupUri = uri;
Шаг (4) немедленно сгенерирует исключение, если конструктор локатора потерпит неудачу, что происходит все время ко мне, с сожалением.
Затем исключение из шага 4 обрабатывается следующим образом ( в этом примере используется RadMessageBox, но вы можете исправить это :
public void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
try
{
var result = this.ShowExceptionDialog(e.Exception);
}
catch
{
RadMessageBox.Show("Fatal Dispatcher Error - the application will now halt.", Properties.Resources.CaptionSysErrMsgDlg,
MessageBoxButton.OK, MessageBoxImage.Stop, true);
}
finally
{
e.Handled = true;
// TERMINATE WITH AN ERROR CODE -1!
//Environment.Exit(-1);
}
}