none
MessageBox.Show() before main window is created

    Question

  • I'm having an odd problem.  I have an application that does some basic validation of data paths and authentication prior to starting up the main window of the application.  In the application Startup event handler, I do some checks, pop up message dialogs if necessary, then if everything checks out I'll create and show the main window of the applications.

    If I have to pop up a message dialog, it's usually due to an error condition in which case I want to show the dialog, let the user dismiss it, then exit the application.  The problem is that any dialogs I pop up prior to the main window being created will pop up for the user and then the application will exit (which is the line after ShowDialog()).  The application doesn't wait for the user to dismiss the dialog before continuing execution.  The dialog works as expected if I create a dummy window and show it prior to any of the dialogs being displayed.  How do I get these dialogs to behave as I expect prior to displaying a Window?  Thanks!

    Thursday, July 23, 2009 8:24 PM

Answers

  • You could try to build the application without App.xaml and check in the Main method arguments

    // C#
      // A Simple WPF Application written without XAML.

      using System;
      
    using System.Windows;
      
    using System.Windows.Controls;
      
    using System.Windows.Threading;

      
    namespace SimpleWPFApp
      
    {
         
    class MyWPFApp : Application
         
    {
            
    [STAThread]
            
    static void Main()
            {

              // Handle key events and then run the application.
              MyWPFApp app = new MyWPFApp();
              
    app.Startup += new StartupEventHandler(AppStartUp);   
              
    app.Exit += new ExitEventHandler(AppExit);
              
    app.DispatcherUnhandledException += new
                
    DispatcherUnhandledExceptionEventHandler(AppUnhandledException);

              // Fires the Startup event.
              app.Run();  
            
    }

            
    static void AppUnhandledException(object sender,  
               
    DispatcherUnhandledExceptionEventArgs e)
            
    {
               
    MessageBox.Show(e.Exception.Message, "Unhandled error!!");
               
    e.Handled = true;
            
    }

            
    static void AppExit(object sender, ExitEventArgs e)
            
    { MessageBox.Show("App has exited"); }

            
    static void AppStartUp(object sender, StartupEventArgs e)
            {

               // Create a Window object and set some basic properties.
               Window mainWindow = new Window();
               
    mainWindow.Title = "My First WPF App!";
               
    mainWindow.Height = 200;
               
    mainWindow.Width = 300;
               
    mainWindow.WindowStartupLocation =
               
    WindowStartupLocation.CenterScreen;
               
    mainWindow.Show();
            
    }
          
    }
        }


    Oscar Avarez Guerras - Arquitecto Software en I3B (I+D+I) Blog:http://geeks.ms/blogs/oalvarez Por favor marca como respuesta si te ha ayudado esta respuesta
    • Marked as answer by JDHarris Friday, July 24, 2009 6:03 PM
    Thursday, July 23, 2009 9:02 PM

All replies

  • You could try to build the application without App.xaml and check in the Main method arguments

    // C#
      // A Simple WPF Application written without XAML.

      using System;
      
    using System.Windows;
      
    using System.Windows.Controls;
      
    using System.Windows.Threading;

      
    namespace SimpleWPFApp
      
    {
         
    class MyWPFApp : Application
         
    {
            
    [STAThread]
            
    static void Main()
            {

              // Handle key events and then run the application.
              MyWPFApp app = new MyWPFApp();
              
    app.Startup += new StartupEventHandler(AppStartUp);   
              
    app.Exit += new ExitEventHandler(AppExit);
              
    app.DispatcherUnhandledException += new
                
    DispatcherUnhandledExceptionEventHandler(AppUnhandledException);

              // Fires the Startup event.
              app.Run();  
            
    }

            
    static void AppUnhandledException(object sender,  
               
    DispatcherUnhandledExceptionEventArgs e)
            
    {
               
    MessageBox.Show(e.Exception.Message, "Unhandled error!!");
               
    e.Handled = true;
            
    }

            
    static void AppExit(object sender, ExitEventArgs e)
            
    { MessageBox.Show("App has exited"); }

            
    static void AppStartUp(object sender, StartupEventArgs e)
            {

               // Create a Window object and set some basic properties.
               Window mainWindow = new Window();
               
    mainWindow.Title = "My First WPF App!";
               
    mainWindow.Height = 200;
               
    mainWindow.Width = 300;
               
    mainWindow.WindowStartupLocation =
               
    WindowStartupLocation.CenterScreen;
               
    mainWindow.Show();
            
    }
          
    }
        }


    Oscar Avarez Guerras - Arquitecto Software en I3B (I+D+I) Blog:http://geeks.ms/blogs/oalvarez Por favor marca como respuesta si te ha ayudado esta respuesta
    • Marked as answer by JDHarris Friday, July 24, 2009 6:03 PM
    Thursday, July 23, 2009 9:02 PM
  • That's basically what's being done now.  The difference is that the AppUnhandledException handler will log errors to our logging system and send out crash reports to the programmers.  So I don't want to hit that path in the case of a known error, I just want to display a dialog to the end user and exit the application.  There are no command line arguments passed to the application that need to be checked.  The tool is a 3D content editor for another set of applications, so prior to starting up the editor there is some permission checking and we verify that renderer resources are where we expect them to be and a few other things.  These checks are done in the AppStartUp (in your example) method prior to the Window being created.  It's done prior to the window being created because the renderer initialization can take a while and we don't want to try to start it (or the rest of the app) if all the preconditions aren't met.  The issue is that if a MessageBox.Show() is inserted into your example in the AppStartUp() method and you follow that with a call to Application.Current.Shutdown(), the dialog will show very briefly and the app will exit before you can read the message or click the button on the dialog.  The expected behavior is that the dialog will show, the user gets a chance to read the message and dismiss it, _then_ the app exits.
    Thursday, July 23, 2009 9:16 PM
  • Hi,

    In an application that I have done, it behaves as you want. shows the MessageBox and the application waits until the user responds to meesagebox. This is the source code

    class MyWPFApp : Application

    {

    [STAThread]

    static void Main()

    {

    // Handle key events and then run the application.

    MyWPFApp app = new MyWPFApp();

    app.Startup += new StartupEventHandler(AppStartUp);

    //app.Exit += new ExitEventHandler(AppExit);

    app.DispatcherUnhandledException += new

    DispatcherUnhandledExceptionEventHandler(AppUnhandledException);

    // Fires the Startup event.

    app.Run();

    }

    static void AppUnhandledException(object sender,

    DispatcherUnhandledExceptionEventArgs e)

    {

    MessageBox.Show(e.Exception.Message, "Unhandled error!!");

    e.Handled = true;

    }

    //static void AppExit(object sender, ExitEventArgs e)

    ////{ MessageBox.Show("App has exited"); }

    static void AppStartUp(object sender, StartupEventArgs e)

    {

    MessageBox.Show("App has ");

    Application.Current.Shutdown();

    // Create a Window object and set some basic properties.

    //Window mainWindow = new Window();

    //mainWindow.Title = "My First WPF App!";

    //mainWindow.Height = 200;

    //mainWindow.Width = 300;

    //mainWindow.WindowStartupLocation =

    //WindowStartupLocation.CenterScreen;

    //mainWindow.Show();

    }

    }


    Oscar Avarez Guerras - Arquitecto Software en I3B (I+D+I) Blog:http://geeks.ms/blogs/oalvarez Por favor marca como respuesta si te ha ayudado esta respuesta
    Thursday, July 23, 2009 9:32 PM
  • Weird.  The only difference is that my application is using an App.xaml.  I'll try messing around with the ShutdownMode and creating the Main() method by hand as you did in your example and we'll see what happens.  That does help in at least giving me a point to investigate.  I'll report back with my results.  Thanks for taking the time to help.
    Thursday, July 23, 2009 9:52 PM
  • Still working on removing the App.xaml.  This is a pain because I have resource dictionaries defined in App.xaml.  I'll post the initialization code here in case anybody has any ideas:

    App.xaml:
    <Application x:Class="OurNamespace.OurApp"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        ShutdownMode="OnMainWindowClose" 
        Startup="OnStartup"  
        Exit="OnExit">
        
        <Application.Resources>
             <!-- stuff here -->
        </Application.Resources>
    </Application>
    OurApp.xaml.cs:
    namespace OurNamespace
    {
        public partial class OurApp
        {
            private void OnStartup(object sender, StartupEventArgs args)
            {
                // Normally one of the mentioned checks would be done here
                if (true) {
                    // If I show this window, then the dialog works as expected
                    //Window w = new Window() { Width=1, Height=1, ShowInTaskbar=false};
                    //w.Show();
    
                    // If I call close on the window, the dialog will show and the app will exit
                    // before the user can click the dialog
                    //w.Close();
                    System.Windows.MessageBox.Show("Test", "Test");
                    Shutdown();
                    return;
                }
            }
        }
    }

    Thursday, July 23, 2009 11:29 PM
  • Hi,

    You must load dictionary of resources in runtime and remove the file app.xaml, in order to load dictionary of resources use this code

    using (FileStream fs = new FileStream("MainResources.xaml", FileMode.Open))
    {
        ResourceDictionary dic
    = (ResourceDictionary) XamlReader.Load(fs);
        Resources.MergedDictionaries.Clear();
        Resources.MergedDictionaries.Add(dic);
    }

    Oscar Avarez Guerras - Arquitecto Software en I3B (I+D+I) Blog:http://geeks.ms/blogs/oalvarez Por favor marca como respuesta si te ha ayudado esta respuesta
    Friday, July 24, 2009 7:49 AM
  • It works if I don't use the App.xaml approach.  Thank you for your help.  Can anybody explain why it doesn't work when using App.xaml?  Thanks again!

    In case anybody else reads this, I wanted to load the resources from the assembly, not as a standalone file from the bin/ folder, this is how to do it:

    ResourceDictionary rd = new ResourceDictionary {Source = new Uri("pack://application:,,,/OurNamespace;component/AppGlobalResourceDictionary.xaml")};
    Resources.MergedDictionaries.Add(rd);


    Friday, July 24, 2009 6:02 PM
  • It works if I don't use the App.xaml approach.  Thank you for your help.  Can anybody explain why it doesn't work when using App.xaml?  Thanks again!
    I have created som of the same code before take a look at this...

    http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/a37709f8-70e4-4eee-a3a2-273e9eda354e


    Kenneth
    Sunday, July 26, 2009 12:07 PM