none
Fechando aplicação ao perder o focu. RRS feed

  • 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 Snippet

    private 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

    domingo, 4 de janeiro de 2009 13:15

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

     

     

    domingo, 4 de janeiro de 2009 16:06

Todas as Respostas

  • Veja se tem algo a ver:

     

    http://support.microsoft.com/kb/952605

     

    domingo, 4 de janeiro de 2009 14:44
  • 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

     

    domingo, 4 de janeiro de 2009 14:51
  • 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));
    }

     

     

    domingo, 4 de janeiro de 2009 16:06