在WPF中撤消/重做集合

时间:2014-03-26 21:00:07

标签: c# wpf datagrid undo-redo

我有一个带有DataGrid的简单WPF屏幕和一些用于剪切,复制,粘贴和删除行的按钮:

enter image description here

我想为所有操作实现Undo/Redo功能,例如剪切/复制/粘贴/添加/删除等。如果它们提供了一些好处,我可以使用其他集合控件而不是DataGrid其他。我已经在stackoverflow.com上讨论了关于同一主题的一些其他问题,但是没有发现它们有用。

2 个答案:

答案 0 :(得分:2)

我认为这个功能最容易使用特殊框架实现,它们通常不大且免费。有许多框架允许您实现Undo/Redo功能。我个人喜欢GuiLabs.Undo,他是我用过的最简单,最舒服的人之一。工作的重点在action

  

每个操作都会对您的域模型进行更改。准备Action的过程明确地与执行它分开。行动的执行可能在准备和安排后的更晚阶段进行。任何Action实现IAction并且基本上提供了两种方法:一种用于实际执行这些操作,另一种用于撤消它。

最重要的是创建一个 AbstractAction 接口类并将其保存在正确的位置。您必须使用ActionManager来保留将来要撤消的操作:

private void SomeActionLogic()
{
    MyAction action = new MyAction(parameter);
    actionManager.RecordAction(action);
}

然后在某个地方使用Undo/Redo

actionManager.Undo();
...
actionManager.Redo();

那么您是否需要考虑如何使用AbstractAction类中的集合?也许这对资源来说是劳动密集型的,因为每次触发Undo/Redo时都需要处理集合。

使用的简单示例,取自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;
    }
}

答案 1 :(得分:1)

您应该实施Command Pattern

使用此模式,每个操作都有一个反作用(重做/撤消)。您在堆栈中保存已应用和未撤消的命令。这将允许您撤消和重做所有命令。 WPF非常适合这种情况,因为您可以将命令直接绑定到元素,而不是普通事件。