在 WPF 中撤消/重做集合 [英] Undo/Redo for Collection in WPF
问题描述
我有一个简单的 WPF 屏幕,带有 DataGrid
和一些用于剪切、复制、粘贴和删除行的按钮:
I have a simple WPF screen with a DataGrid
and some Buttons for Cut, Copy, Paste and Delete row(s):
我想为所有操作实现 Undo/Redo
功能,例如剪切/复制/粘贴/添加/删除等.我愿意使用另一个集合控件而不是 DataGrid代码> 如果它们提供了一些优于其他的好处.我已经在 stackoverflow.com 上解决了一些关于同一主题的其他问题,但发现它们没有用.
I want to implement Undo/Redo
functionality for all the operations like Cut/Copy/Paste/Add/Remove etc. I am open to use another collection controls instead of DataGrid
if they provide some benefit over other. I have gone through some other questions on stackoverflow.com about the same topic but don't find them useful.
推荐答案
我认为使用特殊框架最容易实现此功能,它们通常不大且免费.有许多框架允许您实现Undo/Redo
功能.就个人而言,我喜欢 GuiLabs.Undo
,他是最简单、最舒服的人之一我用过.这项工作的重点在于 action
:
I think this functionality is easiest implemented using special frameworks, they are generally not large and free. There are many frameworks that allow you to implement Undo/Redo
functionality. Personally, I liked GuiLabs.Undo
, he is one of the simplest and most comfortable which I've have used. The whole point of the work is in action
:
每个操作都封装了对域模型的更改.准备 Action 的过程与执行它是明确分开的.一个动作的执行可能会在它准备好和安排好之后的更晚的阶段进行.Any Action 实现了 IAction
并基本上提供了两种方法:一种用于实际执行操作,另一种用于撤消操作.
Every Action encapsulates a change to your domain model. The process of preparing the Action is explicitly separated from executing it. The execution of an action might come at a much later stage after it's been prepared and scheduled. Any Action implements
IAction
and essentially provides two methods: one for actually doing the stuff, and another for undoing it.
最重要的是创建一个AbstractAction接口的类并保存在合适的地方.您必须使用 ActionManager
来保留您将来要撤消的操作:
The most important thing is to create a class of AbstractAction interface and save it in the right place. You have to be using ActionManager
to keep the Action that you want to Undo in the future:
private void SomeActionLogic()
{
MyAction action = new MyAction(parameter);
actionManager.RecordAction(action);
}
然后在某处使用Undo/Redo
:
actionManager.Undo();
...
actionManager.Redo();
那么您是否需要考虑如何使用 AbstractAction
类中的集合?也许它会占用大量资源,因为每次触发Undo/Redo
都需要处理一个集合.
So do you need to consider how you will work with a collection in the AbstractAction
class? Maybe it will be labor-intensive on resources, because every time when triggered Undo/Redo
is necessary to address a collection.
使用的简单示例,取自 这里
:
Simple example of using, taken from here
:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Original color");
SetConsoleColor(ConsoleColor.Green);
Console.WriteLine("New color");
actionManager.Undo();
Console.WriteLine("Old color again");
using (Transaction.Create(actionManager))
{
SetConsoleColor(ConsoleColor.Red); // you never see Red
Console.WriteLine("Still didn't change to Red because of lazy evaluation");
SetConsoleColor(ConsoleColor.Blue);
}
Console.WriteLine("Changed two colors at once");
actionManager.Undo();
Console.WriteLine("Back to original");
actionManager.Redo();
Console.WriteLine("Blue again");
Console.ReadKey();
}
static void SetConsoleColor(ConsoleColor color)
{
SetConsoleColorAction action = new SetConsoleColorAction(color);
actionManager.RecordAction(action);
}
static ActionManager actionManager = new ActionManager();
}
class SetConsoleColorAction : AbstractAction
{
public SetConsoleColorAction(ConsoleColor newColor)
{
color = newColor;
}
ConsoleColor color;
ConsoleColor oldColor;
protected override void ExecuteCore()
{
oldColor = Console.ForegroundColor;
Console.ForegroundColor = color;
}
protected override void UnExecuteCore()
{
Console.ForegroundColor = oldColor;
}
}
这篇关于在 WPF 中撤消/重做集合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!