Pergunta

Suponha que, um formulário de vitória tem certos campos de entrada e usuário digita / re-entra alguns dados.

Como reter dados previamente introduzidos pela operação 'desfazer'?

Apenas quero saber a melhor maneira de realizá-lo.

Foi útil?

Solução

Existem algumas opções. O importante é que você começar a desenhar-lo no início do projeto. Tentando adicioná-lo a um projeto existente pode ser muito caro se não foi projetado com esta capacidade em mente.

Existem alguns padrões fundamentais que você vai querer tirar proveito de:

  1. MVC ou Observer padrão. A primeira chave não é tanto a implementação religiosa ou padrão-fanático de sua arquitetura de alto nível. O é importante é que o software reconhece a diferença entre seu estado atual eo estado exibido e desacopla adequadamente. É preciso haver um comum, claramente definida acoplamento entre o seu estado visual e seu estado de aplicação. Isto proporciona-lhe a arquitetura comum que você precisa para criar um comando (ver # 2).

  2. O padrão Comando . Você ganha um monte de qualidade com o padrão de comando (embora ele pode vir à custa de algum código que parece que deve ser gerado assistente). A abordagem específica que você levar para o padrão de comando pode variar (uma classe por comando com a implementação por meio de substituições contra uma classe por muitos comandos com a implementação através de manipuladores de eventos, por exemplo), mas os comandos são a "ação" de classe que @Ralph sugeriu estruturação de uma pilha ao redor.

    Isso pode ser um pouco complicado, mas a abordagem geral seria para ouvir um evento que iria "comprometer" os dados do estado visual para o estado de aplicação. O evento Validated pode ser uma boa ligar para um Textbox. A Click evento faria mais sentido para uma Button. Quando isso acontece cometer, você cria o comando associado a esse controle, você tentar executar o comando, e você adicionar o comando à sua pilha de desfazer, se o comando for concluído com êxito. Agora você está acompanhando exatamente o que está acontecendo e exatamente os dados que está acontecendo com ele.

  3. O href="http://en.wikipedia.org/wiki/Memento_pattern" rel="noreferrer"> Memento padrão UnExecute() na interface de seu comando, deve ser a última peça central do projeto que você precisa para realizar a sua tarefa.

A coisa agradável sobre uma abordagem estruturada como este é que agora você tem um ponto de extensão natural para o comportamento adicional que precisa acontecer em uma base-de comando. Transações são um ajuste natural, por exemplo. No meu projeto atual, eu estou usando o WPF ICommand de interface (em meus winforms projeto) para fornecer feedback sobre se um determinado comando CanExecute() a qualquer momento. Isto deixa-me ativar e desativar UI widgets de forma apropriada de modo puramente orientada para o comando. :)

A única coisa lamentável é que não há muito apoio para esta estrutura interna para WinForms (tanto quanto eu sei), de forma que você precisa para construir a maior parte dele a partir do zero. Sem única peça é particularmente complicado, mas você pode encontrar-se gerando uma quantidade razoável de código principalmente-clichê para cada comando. É também uma técnica de projeto generalizada. Para ser eficaz, ele has para ser utilizados de forma consistente ao longo das porções apropriadas do pedido. Isso faz com que a adaptação a funcionalidade muito caro, especialmente se o código original está intimamente ligado e incoesa.

Outras dicas

Eu não tenho certeza se WinForms / .Net tem algum tipo de recurso built-in Desfazer que você pode aproveitar. Mas o que você está procurando realmente é uma estrutura de dados Stack para ajudar a gerenciar uma lista de ações. Você vai precisar para criar algum tipo de objeto "ação" para representar as ações que um usuário pode fazer e como progridem através da aplicação que você precisa para empurrar estas ações na pilha. Quando apertar o botão de desfazer, ou Ctrl-Z ou qualquer método para iniciar a ação de desfazer você vai estalar fora a ação atual e restaurar o estado do aplicativo para a ação anterior.

Esta é uma visão muito básico e alto nível de como isso funcionaria, mas imagino que a implementação de tal característica um pode ficar bastante complexo. Basta imaginar como ele precisa trabalhar para um programa como o Adobe Photoshop. : O

Isto pode não ser a melhor maneira de ir sobre ele, dependendo do que você está tentando realizar, mas você poderia usar um richtextbox e invocam o método de desfazer incorporado esse controle.

Por exemplo:

richTextBox1.Undo();

CTRL + Z funciona em controles individuais.

Se você trabalhar com dados e um BindingSource, você pode "desfazer" a não persistiu alterações para o registro (s) chamando o CancelEdit função ou, alternativamente, você pode recarregar os dados para o banco de dados.

A minha sugestão é para determinar os requisitos específicos de desfazer e seus benefícios práticos antes de iniciar o projeto e implementação. Eu herdei um aplicativo WinForms que usou uma desfazer a operação seqüencial múltipla via uma pilha de "ação" genérico objetos internamente. No entanto, descobriu-se que nenhum dos usuários do aplicativo Falei com uso nem solicitou o recurso! E a maneira como este aplicativo em particular funciona, se eu fosse um usuário do aplicativo, eu só iria me vejo usando o recurso de qualquer um.

A funcionalidade Undo poderia ter sido mais útil, neste caso, se fosse uma 'seletiva' desfazer; onde o usuário pode selecionar qualquer única operação / editar de várias edições anteriores feitas, antes de cometer dados e restaurar a única edição ao seu estado original, em vez de apenas ser capaz de desfazer a última operação em primeiro lugar, seguido pelo segundo a última operação , etc., que é como ele foi implementado.

Em qualquer caso, o aplicativo contém, assim, complexidade desnecessária e indireta, tornando mais difícil e mais lento para 'grok' e mudanças fazer e melhorias na funcionalidade existente, neste caso de pouco ou nenhum benefício real. Desde que herdou o projeto, eu implementaram novas funcionalidades, sem desfazer e ninguém tinha quaisquer queixas.

Você também pode encontrou a biblioteca Reversi útil, como vários outros parece ter. Veja [ http://www.codeproject.com/KB/dotnet/ reversibleundoredo.aspx] [1] ou [presente] [2]

[1]: http://www.codeproject.com/KB/dotnet /reversibleundoredo.aspx fazer a sua inscrição reversível ao Suporte desfazer e refazer

[2]: http://www.codeproject.com /script/Articles/Article.aspx?aid=22502 Desfazer Refazer

depende de quantos níveis de desfazer, você deseja ter.

Você pode armazenar valores antes que ele está "empenhada" em algum sentido em uma coleção nível do formulário para cada um dos controles, que você pode "restaurar" no clique de um botão para que o usuário voltar.

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