开发者

How to prevent a WPF app from loading?

I want that the WPF application starts only开发者_如何转开发 in certain conditions. I tried the following with no success:

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        if (ConditionIsMet) // pseudo-code
        {
            base.OnStartup(e);
        }
    }
}

But the app runs normally even when the condition is not met


Try this:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);
    if (MyCondition)
    {
        ShowSomeDialog("Hey, I Can't start because...");
        this.Shutdown();
    }
}


Another solution

Designer

<Application x:Class="SingleInstanceWPF.App"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         Startup="Application_Startup">
</Application>

Code behind

public partial class App : Application
{
    private void Application_Startup(object sender, StartupEventArgs e)
    {
        if (ConditionIsMet)
        {
            var window = new MainWindow();
            window.Show();
        }
        else
        {
            this.Shutdown();
        }
    }
}


It may be that I am doing this the really really hard way, but I have found that fighting with the invocation precedence/order on startup by assuming anything is futile. I really wanted any exception raised during the startup of the application to IMMEDIATELY bubble up to the outermost exception handler, but even when one was raised, my MVVM Locator object was automatically instantiating itself because it is defined as an application-level resource.

That meant that the chicken arrived before the egg but after the same egg had already broken!!!

So the solution was:

1) Remove MVVM Locator from App.xaml.

2) Create an Application_Startup event

Add these lines at the top:

    #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) Tie Startup to the Application_Startup event in App.xaml e.g.

 Startup="Application_Startup"   <<<<  this name is arbitrary but conventional AFAICT

4) In Applicaton_Startup, create the ViewModelLocator like this:

            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) Then, immediately after the resource has been found, open the MainWindow, but only if the Locator was successfully instantiated

            Uri uri = new Uri("pack:Views/MainWindow.xaml", UriKind.RelativeOrAbsolute);
            Application.Current.StartupUri = uri;

Step (4) will throw an exception immediately if the constructor on the Locator fails WHICH HAPPENS ALL THE TIME TO ME, REGRETTTABLY.

Then, the exception from step 4 is handled as follows (this example uses a RadMessageBox but feel free to fix that:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜