【问题标题】:How to implement undo functionality?如何实现撤销功能?
【发布时间】:2011-05-24 20:00:00
【问题描述】:

在我的应用程序中,我想为用户提供一个小的撤消功能。用户可以撤消的操作并不多。特别是行动是:

  • 为对象添加注释
  • 为对象着色
  • 用字符串标记对象

现在我考虑如何实现这一点。我首先想到了一个动作类,它是用户可以采取的 3 种不同动作的抽象基类。每次用户执行这些操作时,都会创建此抽象 Action 类的子类的新适当实例,并将其插入到包含所有操作的列表中。

当用户想要撤消某事时,列表会显示给用户,他可以选择他想要撤消的操作。

现在我在考虑必须在这样的操作对象中存储什么:

  • 动作前对象的状态
  • 实际执行的操作(例如添加到对象注释中的字符串)

我不确定这是否足够。我也想过按时间顺序排列之类的东西,但这应该是必要的,因为列表可以按时间顺序保持正确。

还有什么我应该考虑的吗?

【问题讨论】:

标签: c# .net architecture system-design


【解决方案1】:

撤消/重做通常使用Command Pattern 实现。 Action 类可用作此操作的基础,但您需要在每个命令中执行“执行”操作和“撤消”操作。 Here is an example 在实践中。 您可能应该将执行的命令存储在堆栈中,因为它更容易实现并且更容易让用户遵循。

【讨论】:

    【解决方案2】:

    你可以做这样简单的事情:

    Stack<Action> undoStack = new Stack<Action>();    
    
    void ChangeColor(Color color)
    {
        var original = this.Object.Color;
        undoStack.Push(() => this.Object.Color = original);
        this.Object.Color = color;
    }
    

    【讨论】:

    • 我喜欢这个。从来没有想过要存储实际的动作......非常好。
    【解决方案3】:

    您应该为要撤消的每个操作实施命令模式

    how to implement undo/redo operation without major changes in program

    【讨论】:

      【解决方案4】:

      对于 UNDO 功能的正确和经过验证的实现是命令模式

      【讨论】:

        【解决方案5】:

        在向现有项目添加撤消/重做功能时,很难忽视这个Simple-Undo-redo-library-for-Csharp-NET

        【讨论】:

          猜你喜欢
          • 2011-12-16
          • 2011-05-27
          • 2021-11-25
          • 2020-06-20
          • 2012-12-16
          • 2013-01-30
          • 1970-01-01
          • 2014-02-07
          • 2011-05-09
          相关资源
          最近更新 更多