Orc.Memento Global Undo с несколькими элементами управления
У меня есть необходимость реализовать шаблон отмены-повторного напоминания. Мое приложение имеет несколько вкладок, и на этих вкладках есть несколько элементов управления, которые все реализуют Orc.Memento. Проблема, с которой я сталкиваюсь - это вызов отмены с помощью кнопки меню в MainWindow, а при нажатии кнопки - действие отмены при последнем активном элементе управления.
Редактировать: этот проект, к сожалению, не следует MVVM.
Я выбрал Orc.Memento, потому что его очень легко реализовать без изменения объектов. То, что я сейчас имею, прекрасно работает только с клавишами клавиатуры Ctrl+X и Ctrl+Y. Вызов отмены только отменяет активный контроль. Однако, когда я нажимаю кнопки отмены / возврата в меню 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();
}
}
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 ответ
Вот несколько рекомендаций:
Попробуйте реализовать отмену / повтор в отношении моделей (например, с использованием Orc.ProjectManagement), а не в отношении представлений (так как представления недолговечны
Попробуйте использовать TabControl из Orc.Controls, который позволяет поддерживать все вкладки активными и, таким образом, разрешает повтор / отмену).