在.NET框架中,`DataGridView`控件是用于展示表格数据的常用组件,广泛应用于Windows Forms应用程序。本篇文章将深入探讨如何在C#中为`DataGridView`实现撤销(Undo)和回撤(Redo)功能,这是一项对于用户交互非常重要的功能,尤其是在允许用户编辑表格数据的应用中。 撤销/回撤功能的核心思想是记录用户操作的历史,以便在需要时恢复到之前的状态。在C#中,我们可以使用Memento设计模式来实现这一功能。Memento模式通过保存和恢复对象的内部状态来实现对撤销/回撤的支持。 1. **创建Memento类**: 为`DataGridView`创建一个Memento类,该类存储`DataGridView`在特定时间点的行、列和单元格的数据。包括行的数量、行的索引、每行的单元格数据等。例如: ```csharp public class DataGridViewMemento { private List RowsSnapshot; private List ColumnsSnapshot; // 构造函数用于初始化快照 public DataGridViewMemento(DataGridView dataGridView) { RowsSnapshot = new List(dataGridView.Rows.Cast()); ColumnsSnapshot = new List(dataGridView.Columns.Cast()); } // 提供访问快照的方法 public List Rows { get { return RowsSnapshot; } } public List Columns { get { return ColumnsSnapshot; } } } ``` 2. **实现Undo/Redo栈**: 在你的主程序中,你需要两个栈,一个用于存储撤销操作(UndoStack),另一个用于存储回撤操作(RedoStack)。每次用户进行修改时,都将当前`DataGridView`的状态推送到UndoStack,并清空RedoStack。 ```csharp Stack UndoStack = new Stack(); Stack RedoStack = new Stack(); ``` 3. **监听事件**: 监听`DataGridView`的`CellValueChanged`或`UserDeletingRow`事件,当这些事件触发时,创建一个新的Memento实例并将其推送到UndoStack。 4. **实现Undo操作**: 当用户点击“撤销”按钮时,检查UndoStack是否为空,如果不为空,则弹出顶部的Memento,将`DataGridView`恢复到之前的状态,并将这个Memento推送到RedoStack。 5. **实现Redo操作**: 同理,当用户点击“回撤”按钮时,检查RedoStack是否为空,如果不为空,则弹出顶部的Memento,将`DataGridView`恢复到那个状态,并将这个Memento推送到UndoStack。 6. **注意事项**: - 考虑到性能,不要在每次单元格更改时都创建Memento,而是可以设置一个阈值,例如每5次更改才保存一次状态。 - 处理多线程情况时,确保对UndoStack和RedoStack的访问是线程安全的,可能需要使用`lock`语句或使用`ConcurrentStack`类。 - 考虑到内存占用,可能需要限制UndoStack和RedoStack的大小,超出限制时,丢弃较早的操作记录。 通过以上步骤,你可以为`DataGridView`实现撤销和回撤功能。记住,良好的用户交互体验是软件成功的关键,撤销/回撤功能能够极大地提高用户在处理数据时的满意度和效率。在实际项目中,你可能还需要根据具体需求对这个功能进行扩展,例如处理排序、过滤和分页等操作的撤销/回撤。
2024-11-23 10:58:55 151KB datagridview (C#源码
1
在文章中:https://blog.csdn.net/weixin_42837024/article/details/82184333,实现撤回和回撤功能。 上面提到的文章是用C++实现的,现在用PyQt来重写一下。 """ 有趣的事情 没有结束 2020/3/31 13:45 """ from PyQt5.QtWidgets import (QApplication, QWidget, QUndoCommand, QUndoStack, QUndoView, QGraphicsItem, QGraphicsScene, QGrap
2023-01-17 15:52:02 49KB AND c do
1
2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?.doc
2022-07-09 14:07:21 3.28MB 技术资料
当treeView 控件在编辑时 可能有时需要恢复,但如果没有恢复功能,那样将很难处理,把数据压入栈,又不好控制,如何保存,如何恢复,以下是对操作数据流做的一个保存,便于恢复操作,可撤销 或重做
2022-02-28 15:30:44 71KB c#
1
在Element增删改处 添加 IOperationStack .DO(); 方法,即可将Element的操作过程保存到操作堆                 自行对Element的变化进行记录,以便在IOperation 中Redo Undo中使用
2022-02-09 16:08:21 2.78MB Arcengine Element Redo Undo
1
这里面有两种方式的Element 撤销和重做,一种是自己去实现,另外一种是调用arcgis自带的工具去实现
2022-02-09 12:48:06 2.85MB ArcEngine Element
1
VC6.0/MFC 写的画图程序 有很多功能(画点,直线,矩形,椭圆,圆,正方形,添加文本,undo,redo,删除,可以设置 线形,线宽,线的颜色,填充色,字体)用到很多技巧 比如 双缓冲画图,串行化等谢谢下载使用
2022-01-20 14:51:53 673KB VC VC++ MFC 画图程序
1
在qt下实现了undo的代码
2021-12-24 17:17:29 23KB qt undo
1
代码中应用了QUndoCommand来实现撤销与反撤销操作,希望对你有用。
2021-11-26 16:44:40 879KB Qt撤销
1
实现undo redo功能,多步,绘图。
2021-11-06 12:53:57 64KB redo undo
1