具有多个控件的Orc.Memento全局撤消

时间:2018-07-24 12:19:20

标签: c# wpf catel undo-redo memento

我需要实现一个memento undo-redo模式。我的应用程序有多个选项卡,在这些选项卡中,有多个控件都实现了Orc.Memento。我遇到的麻烦是使用MainWindow上的菜单按钮调用undo,而在按钮操作中最后一个活动控件上调用undo。

编辑:很遗憾,该项目不遵循MVVM。

我选择Orc.Memento是因为它无需修改对象即可轻松实现。现在,只有使用键盘命令Ctrl + X和Ctrl + Y才能正常工作。调用撤消仅对活动控件执行撤消。但是,当我单击MainWindow菜单上的撤消/重做按钮时,我的代码不知道最后一个激活控件来调用撤消/重做。

选项1

选项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();
    }
}

MainWindow

Ctrl + Z和Ctrl + Y映射到此处。撤消/重做方法找到当前活动的控件,然后在该控件上调用撤消/重做。

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的工作方式进行编程,那会很棒。没必要,但是如果您有想法,我的耳朵会张开。

1 个答案:

答案 0 :(得分:1)

以下是一些建议:

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

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