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 ответ

Вот несколько рекомендаций:

  1. Попробуйте реализовать отмену / повтор в отношении моделей (например, с использованием Orc.ProjectManagement), а не в отношении представлений (так как представления недолговечны

  2. Попробуйте использовать TabControl из Orc.Controls, который позволяет поддерживать все вкладки активными и, таким образом, разрешает повтор / отмену).

Другие вопросы по тегам