在 WPF 中撤消/重做集合 [英] Undo/Redo for Collection in WPF

查看:52
本文介绍了在 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆