Usuário com melhor resposta
Fechando aplicação ao perder o focu.

Pergunta
-
Olá pessoal, estou criando um utilitario em wpf que abre ao apertar o quarto botao do mouse, e a ideia é que ele feche ao perder o foco.
Atualmente estou usando o evento onDeactivated da janela como mostra o exemplo abaixo:
Code Snippetprivate
void Window_Deactivated(object sender, EventArgs e){
Close();
}
Só que isso funciona randomicamente. as vezes funciona as vezes nao, e eu nao consegui definir um padrao para isso.
Alguem teria uma ideia melhor.
Muito Obrigado
Dhiogo Ramos Brustolin
Respostas
-
O estabelecimento do handler não é afetado pelo número de instâncias.
Mas eu consegui reproduzir aqui o seguinte comportamento: quando várias instâncias da janela são abertas em sucessão e se clica com o mouse na instância de trás, esta não é ativada, necessitando que se clique novamente (depois de a instância que estava à frente ser fechada) para que haja o ativamento da janela; como a janela não foi ativada em primeiro lugar, ela não pode ser desativada (o evento Deactivated não é disparado), daí não ser fechada quando se clica em outro lugar antes de se clicar sobre ela uma segunda vez etc.
O simples fato de ser possível abrir várias instâncias da janela já indica um problema: a janela será aberta e por padrão ganhará o foco e portanto quando a segunda janela fosse aberta a primeira deveria ser fechada imediatamente. O que acredito estar acontecendo é que o método Close() falhe pelo fato de a janela ainda não ter sido totalmente carregada quando o método Close() é executado imediatamente após a abertura dessa janela pelo fato de outra estar sendo aberta em seguida. Essa falha está afetando alguma coisa (talvez a Z-Order das janelas) e impedindo que a janela de trás ganhe o foco quando clicada.
O que você pode tentar (assumindo, claro, que o problema descrito seja o seu) — parece ter funcionado aqui — é usar uma delegada e o método BeginInvoke() para postar uma mensagem na fila de mensagens da janela invocando um método auxiliar de fechamento. Isso permitirá que todos os eventos de abertura sejam executados antes que o código de fechamento seja invocado. Algo assim:
Declarações e Métodos:
// Delegada para invocação do método Fechar() private delegate void FecharDelegate(); // Método para fechar a instância. private void Fechar() { this.Close();
}
No método handler do evento Deactivated invoque então o método Fechar() através de BeginInvoke():
private void Window_Deactivated(object sender, EventArgs e) { this.Dispatcher.BeginInvoke(new FecharDelegate(Fechar));
}
- Marcado como Resposta Adriel CodecoModerator sábado, 30 de outubro de 2010 20:05
Todas as Respostas
-
-
Nao seria este o caso.
Eu acredito que o problema possa ser quando duas ou mais instancias do programa são abertas muito rapido, nao dando tempo ao aplicativo setar o handler do evento Deactivated do windows, entao a primeira instancia do programa fica aberta até eu setar o focu nela e tirar o foco novamente.
Eu gostaria de achar uma maneira de que a aplicação nao fique aberta se ela nao tiver com o focu, De preferencia que nao use Timer :x
Obrigado
-
O estabelecimento do handler não é afetado pelo número de instâncias.
Mas eu consegui reproduzir aqui o seguinte comportamento: quando várias instâncias da janela são abertas em sucessão e se clica com o mouse na instância de trás, esta não é ativada, necessitando que se clique novamente (depois de a instância que estava à frente ser fechada) para que haja o ativamento da janela; como a janela não foi ativada em primeiro lugar, ela não pode ser desativada (o evento Deactivated não é disparado), daí não ser fechada quando se clica em outro lugar antes de se clicar sobre ela uma segunda vez etc.
O simples fato de ser possível abrir várias instâncias da janela já indica um problema: a janela será aberta e por padrão ganhará o foco e portanto quando a segunda janela fosse aberta a primeira deveria ser fechada imediatamente. O que acredito estar acontecendo é que o método Close() falhe pelo fato de a janela ainda não ter sido totalmente carregada quando o método Close() é executado imediatamente após a abertura dessa janela pelo fato de outra estar sendo aberta em seguida. Essa falha está afetando alguma coisa (talvez a Z-Order das janelas) e impedindo que a janela de trás ganhe o foco quando clicada.
O que você pode tentar (assumindo, claro, que o problema descrito seja o seu) — parece ter funcionado aqui — é usar uma delegada e o método BeginInvoke() para postar uma mensagem na fila de mensagens da janela invocando um método auxiliar de fechamento. Isso permitirá que todos os eventos de abertura sejam executados antes que o código de fechamento seja invocado. Algo assim:
Declarações e Métodos:
// Delegada para invocação do método Fechar() private delegate void FecharDelegate(); // Método para fechar a instância. private void Fechar() { this.Close();
}
No método handler do evento Deactivated invoque então o método Fechar() através de BeginInvoke():
private void Window_Deactivated(object sender, EventArgs e) { this.Dispatcher.BeginInvoke(new FecharDelegate(Fechar));
}
- Marcado como Resposta Adriel CodecoModerator sábado, 30 de outubro de 2010 20:05