Orc.Memento 具有多个控件的全局撤消
Orc.Memento Global Undo with Multiple Controls
我需要实现一个备忘录撤销-重做模式。我的应用程序有多个选项卡,在这些选项卡中有多个控件都实现了 Orc.Memento。我遇到的问题是使用 MainWindow 上的菜单按钮调用撤消,并在最后一个活动控件上调用撤消按钮操作。
编辑:不幸的是这个项目不遵循 MVVM。
我选择了Orc.Memento,因为它非常容易实现,无需修改对象。我现在所拥有的仅适用于键盘命令 Ctrl+X 和 Ctrl+Y。调用撤消只会撤消活动控件。但是,当我单击 MainWindow 菜单上的 undo/redo 按钮时,我的代码不知道调用 undo/redo 的最后一个活动控件。
选项 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();
}
}
}
注意:如果我可以通过自动导航到发生 undo/redo 的控件来编写 Excel 的工作方式,那就太好了。这不是必需的,但如果你有想法,我的耳朵是开放的。
这里有一些建议:
尝试针对模型(例如使用 Orc.ProjectManagement)实施 undo/redo,而不是针对视图(因为视图是短暂的
尝试使用 Orc.Controls 中的 TabControl,它允许您保持所有选项卡处于活动状态,因此允许 redo/undo)。
我需要实现一个备忘录撤销-重做模式。我的应用程序有多个选项卡,在这些选项卡中有多个控件都实现了 Orc.Memento。我遇到的问题是使用 MainWindow 上的菜单按钮调用撤消,并在最后一个活动控件上调用撤消按钮操作。
编辑:不幸的是这个项目不遵循 MVVM。
我选择了Orc.Memento,因为它非常容易实现,无需修改对象。我现在所拥有的仅适用于键盘命令 Ctrl+X 和 Ctrl+Y。调用撤消只会撤消活动控件。但是,当我单击 MainWindow 菜单上的 undo/redo 按钮时,我的代码不知道调用 undo/redo 的最后一个活动控件。
选项 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();
}
}
}
注意:如果我可以通过自动导航到发生 undo/redo 的控件来编写 Excel 的工作方式,那就太好了。这不是必需的,但如果你有想法,我的耳朵是开放的。
这里有一些建议:
尝试针对模型(例如使用 Orc.ProjectManagement)实施 undo/redo,而不是针对视图(因为视图是短暂的
尝试使用 Orc.Controls 中的 TabControl,它允许您保持所有选项卡处于活动状态,因此允许 redo/undo)。