Pergunta

Eu estou escrevendo o que se resume a um editor de documentos. Quando o aplicativo está fechando, eu preciso para solicitar ao usuário para salvar as alterações. Isso é fácil. A minha pergunta é quando é apropriado para não prompt de usuário e, em vez simplesmente dados de descarte que não foram salvas e fechar.

No caso FormClosing, a enumeração CloseReason inclui:

  • Nenhum
  • WindowsShutDown
  • MdiFormClosing
  • UserClosing
  • TaskManagerClosing
  • FormOwnerClosing
  • ApplicationExitCall

I figura que WindowsShutDown e TaskManagerClosing não deve causar um "Salvar alterações?" prompt para aparecer, para impedir que o aplicativo da pendurado com que prompt de exibição.

É esta prática padrão, ou eu deveria estar fazendo outra coisa aqui?

Para maior clareza, aqui está o código:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    base.OnFormClosing(e);

    if (!(e.CloseReason == CloseReason.WindowsShutDown || e.CloseReason == CloseReason.TaskManagerClosing)
            && this.ChangesPending())
    {
        switch (MessageBox.Show(this, "Save changes?", "Save Changes", MessageBoxButtons.YesNoCancel))
        {
            case DialogResult.Yes:
                this.Save();
                break;
            case DialogResult.No:
                // Do nothing
                break;
            case DialogResult.Cancel:
                e.Cancel = true;
                break;
        }
    }
}
Foi útil?

Solução

Eu acho TaskManagerClosing deve ser a única razão que não avisa, se houver. Pessoalmente, eu gostaria de ser solicitado em caso de WindowsShutDown. Se eu estou desligar o Windows com um documento não salvo em algum lugar, isso significa que eu esqueci sobre isso.

Outras dicas

Eu definitivamente também mostram o "Você quer salvar" de diálogo em WindowsShutDown (a aplicação pode por exemplo, têm sido no fundo há algum tempo e que o usuário esqueceu sobre ele, ou ele pode ter clicado em "Restart" após um service pack foi instalado sem pensar duas vezes etc.).

Quanto TaskManagerClosing, eu não mostrar a janela neste caso.

Eu pessoalmente prefiro a apenas perto o programa quando o usuário seleciona próximos, se existem documentos não salvos no tempo perto Eu prefiro manter cópias de backup desses arquivos e informar ao usuário que existem documentos não salvos quando eles próxima abrir o aplicativo .

Eu faço isso por uma série de razões, número um eu como meus aplicações a fechar quando eu dizer-lhes para fechar, eo número dois, mantendo uma cópia temporária do arquivo que atualização I com todas as mudanças como as obras de usuário em que eu proteger contra falhas e fecha de minhas aplicações inesperadas.

Assim, com esta técnica você não precisa se preocupar com ow a aplicação foi encerrada.

Realmente o CloseReason é um ponto discutível, não é? O fato de que seu formulário está indo embora é o que você está tentando recuperar.

Agora você precisa saber se o seu aplicativo já tem lidado com o "save" do evento. Se assim for, o formulário pode ir embora. Você salvou o documento. Mas se não, você pode querer para solicitar ao usuário.

Se você pode validar os dados rapidamente (ou seja, não uma string comparar ou hash de comparar o documento em comparação com os dados no arquivo), então você vai saber se o usuário tiver salvo os dados do formulário.

Caso contrário, se há um monte de campos, e verificando cada um deles é o recurso proibitivo, em seguida, colocar uma bandeira "IsDirty" em seu formulário. Deixe o método Save () definir o IsDirty como falsa, e todos os outros conjuntos de alterações área de TI como True.

Então, em FormClosing, tudo que você precisa é:

protected override void OnFormClosing(FormClosingEventArgs e)
{
    if (isDirty) 
    {
        DialogResult R = MessageBox.Show(this, "Save changes?", "Save Changes", 
                MessageBoxButtons.YesNoCancel);

        if (R == DialogResult.Yes)
        {
            this.Save();
        } else if (R == DialogResult.Cancel)
        {
            e.Cancel = true;
        }
    }
}

Eu acho que mesmo TaskManagerClosing poderia usar uma solicitação para salvar. Se seu aplicativo está respondendo normalmente, fechando-a através do gerenciador de tarefas não deve ser diferente de qualquer outra maneira de fechá-lo. Se for pendurado, não importa o que seu manipulador onClose faz -. Ele nunca vai chegar lá

Eu concordo com @Jerry, na medida em que é mais importante para evitar a solicitação para salvar, se os dados não foi alterado desde a última gravação. Eu costumo usar um simples 'mudou' bandeira, que fica definido em qualquer ação de edição, e liberado em salva e cargas.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top