Como saio de um aplicativo WPF programaticamente?


478

Nos poucos anos em que uso C # (Windows Forms), nunca usei o WPF. Mas agora eu amo o WPF, mas não sei como devo sair do meu aplicativo quando o usuário clica no item de menu Sair no menu Arquivo.

Eu tentei:

this.Dispose();
this.Exit();
Application.ShutDown();
Application.Exit();
Application.Dispose();

Entre muitos outros. Nada funciona.

Respostas:


781

Para sair do seu aplicativo, você pode ligar

System.Windows.Application.Current.Shutdown();

Conforme descrito na documentação do Application.Shutdownmétodo, você também pode modificar o comportamento de desligamento do seu aplicativo especificando um ShutdownMode :

O desligamento é chamado implicitamente pelo Windows Presentation Foundation (WPF) nas seguintes situações:

  • Quando ShutdownMode está definido como OnLastWindowClose.
  • Quando o ShutdownMode estiver definido como OnMainWindowClose.
  • Quando um usuário encerra uma sessão e o evento SessionEnding é não tratado ou tratado sem cancelamento.

Observe também que Application.Current.Shutdown();só pode ser chamado a partir do thread que criou o Applicationobjeto, ou seja, normalmente o thread principal.


8
Como apontei, não é estranho. No aplicativo WPF, é uma classe estática. Application.Current é uma referência ao seu aplicativo em execução no momento.
TimothyP

4
Na minha opinião, é um pouco estranho no sentido de que isso não seja óbvio à primeira vista e se desvia apenas o suficiente dos modelos anteriores para afastar as pessoas. Faz todo o sentido que funcione, é claro.
quer

20
Se você ligar, Application.Current.Shutdown();sua função não retornará imediatamente. Você precisa ligar return;também para isso.
Erwin Mayer

2
Eu usei isso em que de uma janela aparece outra e, no evento window_closed dessa janela, adicionei esse código. todas as janelas desaparecem, mas o programa ainda roda além do local após a criação do pop-up.
diyoda_

7
@ TimothyP Não ApplicationNÃO é uma classe estática. Ter um Application.Currentmembro estático não significa que é estático. Em vez disso, é uma classe normal que pode ser derivada.
Earth Engine

156

Se você realmente precisar encerrar, também poderá usar Environment.Exit () , mas não é nada gracioso (mais como encerrar o processo).

Use-o da seguinte maneira:

Environment.Exit(0)

4
Environment.Exit()precisa de pelo menos um parâmetro, um código de saída. Use Environment.Exit(0)se você não estiver preocupado com o código de saída.
gbmhunter 23/05

24
Este método realmente fechou tudo. Meu aplicativo estava deixando algo em execução (o formulário foi fechando, mas um processo ainda estava correndo) comApplication.Current.Shutdown();
gbmhunter

4
Environment.Exit é definitivamente o caminho certo para garantir o desligamento de um aplicativo. Com Application.Current.Shutdown, você pode facilmente terminar com o aplicativo em execução indefinidamente, se você tiver um código que retorne ao despachante.
Marcus Andrén

Tão igual quanto Application.exit (0);
Sayka 17/02/2015

Com o Application.Current.Shutdown();meu Closingevento foi chamado, quando eu simplesmente queria desligar meu aplicativo imediatamente. Então Environment.Exit(0);foi a melhor escolha.
FredM

64

Como o wuminqi disse , Application.Current.Shutdown();é irreversível e acredito que é normalmente usado para forçar o fechamento de um aplicativo em momentos como quando um usuário está efetuando logoff ou desligando o Windows.

Em vez disso, ligue this.close()na sua janela principal. É o mesmo que pressionar Alt+ F4ou fechar o botão [x] na janela. Isso fará com que todas as outras janelas de propriedade sejam fechadas e acabará chamando Application.Current.Shutdown();desde que a ação de fechamento não tenha sido cancelada. Consulte a documentação do MSDN em Fechando uma janela .

Além disso, como this.close()é cancelável, você pode colocar uma caixa de diálogo de confirmação para salvar alterações no manipulador de eventos de fechamento. Basta criar um manipulador de eventos <Window Closing="...">e alterar de e.Cancelacordo. (Consulte a documentação do MSDN para obter mais detalhes sobre como fazer isso.)


2
+1 Decidi seguir com este, principalmente porque preciso salvar os arquivos abertos antes de sair do aplicativo.
AgentKnopf

2
Uma coisa importante a ser observada aqui é o fato de Allen apontar um fato muito importante: todas as outras janelas de propriedade serão fechadas. Você precisa se certificar de que declara propriedade. Se você tiver uma janela em execução e abrir outra janela, mas ainda não a mostrar, depois de fechar a janela ativa, a janela oculta forçará o aplicativo a continuar em execução. Você terá um vazamento de memória em potencial, a menos que feche essa janela por outros meios (gerenciador de tarefas, etc.). Eu testei isso.
BK

35

Use qualquer um dos seguintes, conforme necessário:

1

 App.Current.Shutdown();
OR
 Application.Current.Shutdown();

2)

 App.Current.MainWindow.Close();
OR
 Application.Current.MainWindow.Close();

Acima de todos os métodos, a chamada closing eventde Windowclasse e a execução podem parar em algum momento (porque geralmente os aplicativos colocam diálogos como 'você tem certeza?' Ou ' Deseja salvar dados antes de fechar? ', Antes que uma janela seja fechada completamente)

3. Mas se você deseja finalizar o aplicativo sem nenhum aviso imediato. Use abaixo

   Environment.Exit(0);


18

Aqui está como eu faço o meu:

// Any control that causes the Window.Closing even to trigger.
private void MenuItemExit_Click(object sender, RoutedEventArgs e)
{
    this.Close();
}

// Method to handle the Window.Closing event.
private void Window_Closing(object sender, CancelEventArgs e)
{
    var response = MessageBox.Show("Do you really want to exit?", "Exiting...",
                                   MessageBoxButton.YesNo, MessageBoxImage.Exclamation);
    if (response == MessageBoxResult.No)
    {
        e.Cancel = true;
    }
    else
    {
        Application.Current.Shutdown();
    }
}

Eu só peço a Application.Current.ShutDown()partir da janela principal do aplicativo, todas as outras janelas usam this.Close(). Na minha janela principal, Window_Closing(...)lida com o xbotão superior direito . Se algum dos métodos solicitar a janela mais próxima, Window_Closing(...)agarre o evento para desligar se o usuário confirmar.

O motivo pelo qual realmente uso Application.Current.Shutdown()na minha janela principal é que notei que se um erro de design fosse cometido e eu não declarasse um pai de uma das minhas janelas em um aplicativo, se essa janela fosse aberta sem ser exibida antes até o último fechamento da janela ativa, fiquei com uma janela oculta em execução em segundo plano. O aplicativo não será desligado. A única maneira de impedir o vazamento completo de memória é entrar no Gerenciador de tarefas para desligar o aplicativo. Application.Current.Shutdown()me protege de falhas de design não intencionais.

Isso é da minha experiência pessoal. No final, use o que é melhor para o seu cenário. Esta é apenas mais uma informação.


16

Não deve haver uma mensagem Application.ShutDown();ou .Exit().

Applicationé uma classe estática. Não se refere ao aplicativo atual. Você precisa acessar o aplicativo atual e desligá-lo assim:

Application.Current.Shutdown();

8

Outra maneira de fazer isso:

System.Diagnostics.Process.GetCurrentProcess().Kill();

Isso forçará a matar seu aplicativo. Sempre funciona, mesmo em um aplicativo multiencadeado.

Nota: Apenas tome cuidado para não perder dados não salvos em outro encadeamento.


Isso parece incompreensível: "no processo sempre funciona" . Consegues consertar isso? Ou pelo menos explique aqui nos comentários o que você quer dizer?
Peter Mortensen

Isso também é parcialmente incompreensível: apenas se preocupe com um aplicativo que salva dados em arquivos de outro encadeamento. Consegues consertar isso? Ou pelo menos explique aqui nos comentários o que você quer dizer?
Peter Mortensen

Você está usando o Google Tradutor?
Peter Mortensen

não, eu não, minha média é quando o aplicativo está sendo executado como multiencadeamento e você está usando Process.Kill, ele funcionará, mas de outra maneira como esta.close não funciona em aplicativos multithread quando outro encadeamento está em execução.
Ali Yousefi

6
private void _MenuExit_Click(object sender, RoutedEventArgs e)
{
   System.Windows.Application.Current.MainWindow.Close();
}

//Override the onClose method in the Application Main window

protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    MessageBoxResult result =   MessageBox.Show("Do you really want to close", "",
                                          MessageBoxButton.OKCancel);
    if (result == MessageBoxResult.Cancel)
    {
       e.Cancel = true;
    }
    base.OnClosing(e);
}

esta não é a resposta da pergunta, ele só quer saber como sair do aplicativo wpf.
Mehdi

6

Tentar

App.Current.Shutdown();

Para mim

Application.Current.Shutdown(); 

não funcionou.


6

Segundo o meu entendimento, Application.Current.Shutdown()também tem sua desvantagem.

Se você deseja mostrar uma janela de confirmação para permitir que os usuários confirmem ao sair ou não, Application.Current.Shutdown()é irreversível.


7
Eu não entendo isso. No Application.Current.Shutdown()entanto, podemos obter confirmação do usuário antes de ligar .
Amsakanna

2
Não vejo por que você deveria confirmar. Muitas confirmações são uma coisa muito ruim. O fato de alguém ter se esforçado para clicar para abrir o menu Arquivo, ir até a parte inferior do menu Arquivo e clicar em Sair, é bastante confirmado de que não deseja mais usar o aplicativo.

Veer: No meu caso, a janela de confirmação aparece, mas mesmo quando você escolhe "cancelar" na confirmação, o aplicativo principal sai.
Wuminqi 14/05

7
JTS: É melhor ser projetado caso a caso. Nosso aplicativo, se há trabalhos em execução, a saída de força irá causar danos, então é melhor deixá-los informados no diálogo de confirmação
wuminqi

3

Resumindo, existem algumas maneiras de fazer isso.

1) Matando o processo, que pula a finalização, tratamento de erros, etc .:

Process.GetCurrentProcess().Kill();

2) Desligando o aplicativo atual, que provavelmente é a maneira correta, porque chama os eventos de saída:

Application.Current.Shutdown();

ou

this.Shutdown();

(quando agrupado em uma instância da classe App)

3) Fechando o aplicativo atual (todos os formulários precisam ser fechados / finalizados anteriormente):

this.Close(); 

(quando agrupado em uma instância da classe App)

4) Saindo do ambiente, que finaliza o aplicativo:

Environment.Exit(0);

Além disso, você pode querer ler sobre estatutos de saída aqui


2

Caliburn micro sabor

public class CloseAppResult : CancelResult
{
    public override void Execute(CoroutineExecutionContext context)
    {
        Application.Current.Shutdown();
        base.Execute(context);
    }
}

public class CancelResult : Result
{
    public override void Execute(CoroutineExecutionContext context)
    {
        OnCompleted(this, new ResultCompletionEventArgs { WasCancelled = true });
    }
}

O que significa "Caliburn micro flavored" ?
Peter Mortensen

Como você alcançá-lo usando Caliburn Micro
Anders

0

Se você deseja sair de outro encadeamento que não criou o objeto de aplicativo, use:

System.Windows.Application.Current.Dispatcher.InvokeShutdown();

-2

Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;


2
Bem-vindo ao SO, Alpha-LIon! As respostas somente de código são desencorajadas aqui, pois não fornecem uma visão de como o problema foi resolvido. Por favor, atualize sua solução com uma explicação de como seu código resolve o problema do OP :)
Joel

-3

No código xaml, você pode chamar um SystemCommand predefinido:

Command="SystemCommands.MinimizeWindowCommand"

Eu acho que essa deve ser a maneira preferida ...


Minimizar! = Sair do aplicativo. Não vejo uma opção de aplicativo de saída nessa lista. Parece mais gerenciamento de janelas e fechar janela não significa necessariamente fechar o aplicativo. msdn.microsoft.com/en-us/library/…
kenny
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.