首页 > 解决方案 > Orc.Memento 具有多个控件的全局撤消

问题描述

我需要实现一个纪念品撤消重做模式。我的应用程序有多个选项卡,在这些选项卡中有多个控件,它们都实现了 Orc.Memento。我遇到的麻烦是使用 MainWindow 上的菜单按钮调用撤消,并在最后一个活动控件上的按钮操作调用撤消。

编辑:不幸的是,这个项目不遵循 MVVM。

我选择 Orc.Memento 是因为它非常容易实现而无需修改对象。我现在只有使用键盘命令 Ctrl+X 和 Ctrl+Y 才能很好地工作。调用 undo 只会在活动控件上撤消。但是,当我单击 MainWindow 菜单上的撤消/重做按钮时,我的代码不知道调用撤消/重做的最后一个活动控件。

选项1

选项一是通过设置每个控件的全局属性来跟踪最后一个活动GotFocus()控件。我觉得必须有更好的方法。

选项 2

这就是我在这里的原因:-)。


控制

public class MyControl : IMemento
{
    private MementoService mementoService = new MementoService();

    public void RegisterAll()
    {
        mementoService.RegisterObject(myObject);
        mementoService.RegisterCollection(myCollection);
    }

    public void Undo()
    {
        mementoService.Undo();
    }

    public void Redo()
    {
        mementoService.Redo();
    }
}

主窗口

Ctrl+Z & Ctrl+Y 映射到这里。undo/redo 方法找到当前活动的控件并在该控件上调用 undo/redo。

public MainWindow
{   
    /// <summary>
    /// Call undo on the currently active control
    /// </summary>
    public void Undo()
    {
        /*
         * get current focused control.
         * find the parent that is an IMemento. And call Redo on that control
         */
        var focusedControl = FocusManager.GetFocusedElement(this);
        var mementoControl = UIHelper.TryFindParentThatIsIMemento<Control>(focusedControl as DependencyObject);

        /*
         * Call Undo on the control that is currently active
        */
        if (mementoControl != null && mementoControl is IMemento)
        {
            var mem = (mementoControl as IMemento);
            mem.Undo();
        }
    }
}

注意:如果我可以通过自动导航到发生撤消/重做的控件来编程 Excel 的工作方式,那就太好了。这不是必需的,但如果你有一个想法,我的耳朵是敞开的。

标签: c#wpfcatelundo-redomemento

解决方案


这里有一些建议:

  1. 尝试针对模型实施撤消/重做(例如使用 Orc.ProjectManagement),而不是针对视图(因为视图是短暂的

  2. 尝试使用 Orc.Controls 中的 TabControl,它允许您保持所有选项卡处于活动状态,从而允许重做/撤消)。


推荐阅读