Как реализовать операцию "отменить" в приложении .net windows?

Предположим, что форма выигрыша имеет определенные поля ввода, и пользователь вводит/повторно вводит некоторые данные.

Как сохранить данные, ранее введенные с помощью операции "отменить"?

Просто я хочу знать, как лучше всего это сделать.

Ответ 1

Есть несколько вариантов. Важно то, что вы начинаете разрабатывать его в начале проекта. Попытка добавить его к существующему проекту может быть очень дорогой, если она не была разработана с учетом этой возможности.

Есть несколько фундаментальных шаблонов, которые вы захотите использовать:

  • MVC или Observer pattern, Первый ключ - это не столько религиозная, либо паттерн-фанатичная реализация вашей архитектуры высокого уровня. Важно то, что ваше программное обеспечение распознает разницу между текущим состоянием и отображаемым состоянием и соответствующим образом отделяется. Должна существовать общая четко определенная связь между вашим визуальным состоянием и состоянием вашего приложения. Это дает вам общую архитектуру, необходимую для создания команды (см. № 2).

  • Command. Вы получаете много качества с помощью шаблона команды (хотя это может произойти за счет некоторого кода, который выглядит так, как будто он должен быть создан мастером). Конкретный подход, который вы применяете к шаблону команды, может отличаться (один класс для каждой команды с реализацией через переопределения по сравнению с одним классом для многих команд с реализацией через обработчики событий, например), но команды - это класс действия, который @Ralph предложил структурировать стек вокруг.

    Это может быть немного сложно, но общим подходом было бы прослушивание события, которое "фиксировало" данные из визуального состояния в состояние приложения. Событие Validated может быть хорошим крюком для Textbox. Событие Click имеет смысл для Button. Когда это происходит, вы создаете команду, связанную с этим элементом управления, вы пытаетесь выполнить эту команду, и вы добавляете команду в ваш undo-стек, если команда завершается успешно. Теперь вы точно отслеживаете, что происходит, и точно данные, с которыми оно происходит.

  • Memento. @JP Вытащил последний кусочек головоломки. Вы можете использовать память в сохраненной команде для хранения того, что было затронутым состоянием управления, перед выполнением команды. Это, в сочетании с членом UnExecute() на вашем командном интерфейсе, должно быть последним основным элементом дизайна, который вам нужен для выполнения вашей задачи.

Хорошо, что подобный структурированный подход состоит в том, что теперь у вас есть естественная точка расширения для дополнительного поведения, которое должно выполняться на основе команд. Например, транзакции являются естественными. В моем текущем проекте я использую WPF ICommand интерфейс (в моем проекте winforms), чтобы предоставить отзыв о том, является ли заданная команда CanExecute() в любой момент времени. Это позволяет мне включать и отключать виджеты пользовательского интерфейса соответствующим образом с помощью командной строки.:)

К сожалению, не так много поддержки этой структуры, встроенной в Winforms (насколько мне известно), поэтому вам нужно будет собрать большую часть с нуля. Никакая отдельная деталь не является особенно сложной, но вы можете обнаружить, что для каждой команды имеется довольно много стандартного кода. Это также широко распространенная техника дизайна. Чтобы он был эффективным, он должен использоваться последовательно в соответствующих частях приложения. Это делает переоснащение функциональности довольно дорогостоящим, особенно если исходный код тесно связан и несовместим.

Ответ 2

Я не уверен, что WinForms/.Net имеет встроенную функцию отмены, которую вы можете использовать. Но то, что вы действительно ищете, - это структура данных стека, которая поможет вам управлять списком действий. Вам нужно будет создать объект типа "действия" для представления действий, которые пользователь мог бы сделать, и по мере их прохождения через приложение вам нужно будет вытолкнуть эти действия в стек. Когда они нажимают кнопку отмены или Ctrl-Z или какой-либо другой способ инициирования действия отмены, вы удаляете текущее действие и восстанавливаете состояние приложения до предыдущего действия.

Это очень простой и высокоуровневый обзор того, как это будет работать, но я полагаю, что реализация такой функции может стать довольно сложной. Представьте себе, как он должен работать для такой программы, как Adobe Photoshop.: О

Ответ 3

Это может быть не самый лучший способ сделать это в зависимости от того, что вы пытаетесь выполнить, но вы можете использовать richtextbox и вызвать метод отмены, встроенный в этот элемент управления.

Например:

richTextBox1.Undo();

Ответ 5

CTRL + Z работает с отдельными элементами управления.

Если вы работаете с данными и BindingSource, вы можете "отменить" не сохраняемые изменения в записи, вызвав CancelEdit или, альтернативно, вы можете перезагрузить данные для базы данных.

Ответ 6

Мое предложение состоит в том, чтобы определить конкретные требования отмены и его практические преимущества перед началом проектирования и реализации. Я унаследовал приложение WinForms, которое использовало последовательную отмену нескольких операций через стек общих объектов "действия" внутри. Однако оказалось, что ни один из пользователей приложения, с которым я разговаривал, не использовал эту функцию! И как работает это конкретное приложение, если бы я был пользователем приложения, я просто не видел бы себя использовать эту функцию.

В этом случае функциональность Undo была бы более полезной, если бы это было "выборочное" отмена; где пользователь мог выбрать любую отдельную операцию/редактирование нескольких предыдущих изменений, сделанных до фиксации данных, и восстановить это единственное редактирование в исходное состояние, вместо того, чтобы только сначала отменить последнюю операцию, а затем выполнить вторую и последнюю операцию и т.д., как это было реализовано.

В любом случае приложение, таким образом, содержит ненужную сложность и косвенность, что делает его сложнее и медленнее "grok", а также вносит изменения и улучшения в существующие функциональные возможности, в этом случае практически не приносит реальной выгоды. Поскольку я унаследовал проект, я внедрил новые функции без отмены, и никто не жаловался.

Ответ 7

Вы также можете найти библиотеку Reversi полезной, как, например, несколько других. См. [http://www.codeproject.com/KB/dotnet/reversibleundoredo.aspx][1] или [this] [2]

[1]: http://www.codeproject.com/KB/dotnet/reversibleundoredo.aspx Сделайте свое приложение обратимым для поддержки отмены и повтора

[2]: http://www.codeproject.com/script/Articles/Article.aspx?aid=22502 Отменить повтор

Ответ 9

Зависит от количества уровней отмены, которые вы хотите иметь.

Вы можете хранить значения до того, как они будут "переданы" в некотором смысле в коллекцию уровня формы для каждого элемента управления, которую вы можете "Восстановить" нажатием кнопки, чтобы пользователь мог вернуться назад.