【问题标题】:Nested undo/redo operations with PostSharpPostSharp 的嵌套撤消/重做操作
【发布时间】:2015-05-01 17:03:25
【问题描述】:

我刚刚开始使用 PostSharp,目前用于提供撤消/重做功能,但将来可能会提供更多功能。

我想知道是否有任何方法可以在我们的应用程序中实现一组嵌套操作。

所以我在主应用程序中有我的对象模型,然后我启动一个编辑器窗口来修改消息列表。我可以正确地让 PostSharp 监控我对每条消息所做的所有单独更改,并允许用户撤消这些更改。到目前为止一切顺利。

然后我想要的是允许用户退出编辑器,现在在撤消堆栈上有一个操作 - “撤消消息更改”或类似的东西。这将涉及获取所有单独的更改并在编辑器被解雇时将它们合并到一个操作中。 我目前正在研究 OperationScope 方法,但我不确定我是否朝着正确的方向前进。当在作用域内时,操作不会立即添加到撤消堆栈中,它们仅在作用域关闭时才添加,这不是我想要的。

我已经包含了我的测试代码的一个非常精简的示例,以及一些关于我在不同点上的期望的 cmet。可能是我想要的东西是不可能的,但希望有人能提出一些建议!

    private void btnShowEditor_Click(object sender, EventArgs e)
    {
        // Nothing on the undo stack at this point
        LaunchEditorWindow();

        // I would like one composite operation at this point that can undo all of the changes made within LaunchEditorWindow
    }

    // Imagine this code is inside an editor window and the changes are being done by the user
    private void LaunchEditorWindow()
    {
        _network.Messages.Add(new Message() { Name = "Message 1", BitLength = 1 });

        // I would expect there to be three undo operations available here
        System.Diagnostics.Debug.WriteLine(RecordingServices.DefaultRecorder.UndoOperations.Count);

        _network.Messages.Add(new Message() { Name = "Message 2", BitLength = 2 });

        // 6 operations now
        _network.Messages.Add(new Message() { Name = "Message 3", BitLength = 3 });

        // etc etc
        _network.Messages.Add(new Message() { Name = "Message 4", BitLength = 4 });

        System.Diagnostics.Debug.WriteLine(RecordingServices.DefaultRecorder.UndoOperations.Count);
    }

【问题讨论】:

    标签: c# postsharp


    【解决方案1】:

    PostSharp 撤消/重做有一个嵌套操作的概念,但这个概念没有暴露给公共 API:它在内部用于支持原子操作。不向用户公开树形结构的理由是用户通常期望线性结构。

    OperationScope 不允许您向用户公开层次结构。范围可以是分层的,但操作会自动“扁平化”,即新范围并不总是导致新操作(如果父操作存在,则重用它,除非新范围是原子的)。

    您可以调查还原点(请参阅http://doc.postsharp.net/m_postsharp_patterns_recording_recorder_addrestorepoint_762235a2)。

    看来您想要的是将所有操作从还原点到当前点合并为给定名称的新操作的能力。当前的 API 不允许这样做。我添加了功能请求http://postsharp.uservoice.com/forums/4949-feature-requests/suggestions/7776894-undo-redo-api-to-merge-operations,并鼓励您投票。

    请注意,您可以通过在 Recorder.UndoOperations 顶部创建自定义“视图模型”来自行实现该功能,该模型将使用对您有意义的聚合级别显示操作。这是一个明智的选择,因为它可以让您完全控制用户对撤消/重做系统的看法,这基本上是您想要的。但是,这意味着您必须创建自己的撤消/重做按钮。

    【讨论】:

    • 感谢 Gael 的回复,在发布我的问题后不久,我意识到我应该查看还原点机制,并且我可能最终会使用这些还原点作为标记,以便我们一旦他们关闭了我们的编辑器,就可以向用户展示一个单一的撤消。我已经对您创建的 UseVoice 问题进行了投票,祈祷它的结果!我原以为这是一个相对普遍的要求。我会将我对实际(理想)功能实现的想法添加到 UserVoice 票证中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-22
    • 2018-08-23
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 2011-01-07
    • 2014-07-07
    相关资源
    最近更新 更多