System.Windows.MessageBox não aguarda a input do usuário antes de ir poof!

… e não faz sentido porque. TT

No meu manipulador de events Application_Startup eu tenho código que se parece com isso:

 private void Application_Startup(object sender, StartupEventArgs e) { string errorMessage; if(CheckStartUpConditions(out errorMessage)) { (new MainWindow()).Show(); } else { MessageBox.Show(errorMessage, "Application Startup", MessageBoxButton.OK, MessageBoxImage.Error); Shutdown(); } } private bool CheckStartUpConditions(out string errorMessage) { errorMessage = string.Empty; if(...) errorMessage += "Please login to xxx. "; if(...) errorMessage += "Please install xxx."; if(string.IsNullOrEmpty(errorMessage)) return true; else return false; } 

A checkbox de mensagem faz uma breve aparição por um segundo antes de ir “POOF!” Não me espera clicar em “OK” ou no botão “X”. Eu estou realmente perplexo a respeito de porque isso está ocorrendo, então qualquer ajuda seria muito apreciada .

Eu tentei comentar a chamada para Shutdown apenas por diversão e risos, e ainda se comporta da mesma maneira.

Além disso, o aplicativo também tem um SplashScreen , então não sei se isso está afetando isso.

EDIT: eu adicionei mais código se isso ajuda. A checkbox de mensagem está mostrando a mensagem de erro correta. Só não vai ficar tempo suficiente para os usuários lerem. > 🙁

EDITAR PARTE 2: Ok … acho que encontrei o culpado. 🙁 Alterei a ação de compilation da imagem que estou usando como respingo do SplashScreen para Nenhum e a checkbox de mensagens agora ficará e aguardará a input do usuário. Não entendo por que o SplashScreen está aparafusando com o MessageBox.>: (

Tente usar uma sobrecarga que aceite o parâmetro System.Windows.Window e passe o valor Null para tornar seu MessageBox uma janela de nível superior do seu aplicativo, que é independente de todas as outras janelas que possam existir. Eu acho que o seu MessageBox é de propriedade do formulário splashscreen. Quando a canvas inicial é fechada, a estrutura fecha o MessageBox. Então, fazer o seu MessageBox sem dono deve fazer o truque.

Com base na sugestão de Alexey Ivanov, usei com sucesso uma nova janela como pai

 System.Windows.Forms.MessageBox.Show(new System.Windows.Forms.NativeWindow(), errorMessage, "Application Startup", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); 

A checkbox de mensagem desaparece imediatamente porque não tem proprietário. Se você especificar a opção MessageBoxOptions.DefaultDesktopOnly , a área de trabalho será atribuída como proprietária e a checkbox de mensagem funcionará corretamente em um aplicativo sem janela principal.

 MessageBox.Show( "Message", "Title", MessageBoxButton.YesNoCancel, MessageBoxImage.Question, MessageBoxResult.Cancel, MessageBoxOptions.DefaultDesktopOnly); 

Crie uma janela oculta transparente e use-a como proprietária da MessageBox:

 private Window CreateHiddenWindow() { var window = new Window { AllowsTransparency = true, Background = System.Windows.Media.Brushes.Transparent, WindowStyle = WindowStyle.None, Top = 0, Left = 0, Width = 1, Height = 1, ShowInTaskbar = false }; window.Show(); return window; } 

Você pode manter sua canvas inicial e usar um MessageBox WPF padrão se implementar a canvas inicial no código em vez de uma ação de compilation da imagem.

App.xaml.cs:

 var splashScreen = new SplashScreen("path/to/splash_image.bmp"); splashScreen.Show(false); //make sure to use 'false' here to prevent auto-closing string errorMessage; if(CheckStartUpConditions(out errorMessage)) { (new MainWindow()).Show(); } else { //standard WPF MessageBox may now be used here MessageBox.Show(errorMessage, "Application Startup", MessageBoxButton.OK, MessageBoxImage.Error); Shutdown(); } //explicitly close the splash screen now splashScreen.Close(TimeSpan.FromSeconds(1)); 

Alexey está certo, a canvas inicial fecha a checkbox de mensagens.

Uma maneira simples de evitar isso é usar a function MessageBox nativa:

 [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type); public static void Main() { ... MessageBox(new IntPtr(0), "Hello World!", "MyApp", 0); 

Você precisa dizer ao WPF para não desligar quando a primeira janela aparecer. Veja isto: http://msdn.microsoft.com/pt-br/library/system.windows.application.shutdownmode.aspx . Você deseja configurar seu aplicativo para ser encerrado explicitamente (em vez de após a primeira janela ser fechada):

   

Sua outra escolha é definir sua MainWindow como StartupUri (em vez de sua canvas inicial) e, em seguida, carregar sua canvas inicial no evento carregado da MainWindow. Em seguida, você faria qualquer coisa de carregamento ou tempo intensivo que precisasse fazer, ocultasse sua canvas inicial e mostrasse novamente sua janela principal.