Я не могу заставить Undo и Redo правильно вести себя при использовании диалога.Как реализовать диалог изменения состояния с поддержкой отмены/повтора в Catel?
У меня есть простая модель со свойствами, указывающими состояние объекта (running
, paused
, stopped
), которые могут быть изменены с помощью диалогового окна. Случается, что я получаю действия, которые, кажется, ничего не делают в моей очереди отмены или отменят, возвращают объект в промежуточное состояние.
Объект модели зарегистрирован в memento в конструкторе. В диалоговом окне есть три переключателя, каждый из которых представляет одно из трех разных состояний. Каждый переключатель используется для каждой команды. Каждая команда выполняет изменение свойства. Я пробовал два разных подхода, либо каждая команда устанавливает свойство непосредственно в объекте, либо каждая команда устанавливает переменную экземпляра для модели представления при вызове, а затем я использую событие Saving для изменения объекта.
Если вы используете первый подход, каждое изменение свойств помещается в очередь Undo, если пользователь нажимает больше, чем один радиообъект, прежде чем нажимать Ok в диалоговом окне. Пытался решить это, обернув весь диалог в пакет, но это приведет к отмене изменения состояния, объект возвращается в состояние, которое оно имело до окончательного, т. Е. Если для свойства было установлено значение stopped
перед открытием диалогового окна и нажатие кнопки затем запустите одно и, наконец, Ok, undo установит свойство на paused
вместо ожидаемого stopped
.
Если вы используете второй подход, пользователь открывает диалоговое окно, измените его на paused
, нажмите «ОК» в диалоговом окне «Отменить/повторить», как и следовало ожидать, но если диалог снова откроется, а «Отмена» будет добавлено еще одно действие очередь Undo, то есть пользователь должен дважды нажать «Отменить», чтобы вернуться к исходному состоянию stopped
.
Итак, мой вопрос заключается в том, как это должно быть правильно реализовано для получения ожидаемого поведения; что каждое диалоговое взаимодействие можно отменить, а не каждое взаимодействие в диалоговом окне?
Вот код для ViewModel:
namespace UndoRedoTest.ViewModels
{
using Catel.Data;
using Catel.MVVM;
public class StartStopViewModel : ViewModelBase
{
Machine.MachineState _state;
public StartStopViewModel(Machine controlledMachine)
{
ControlledMachine = controlledMachine;
_state = controlledMachine.State;
StartMachine = new Command(OnStartMachineExecute);
PauseMachine = new Command(OnPauseMachineExecute);
StopMachine = new Command(OnStopMachineExecute);
Saving += StartStopViewModel_Saving;
}
void StartStopViewModel_Saving(object sender, SavingEventArgs e)
{
ControlledMachine.State = _state;
}
[Model]
public Machine ControlledMachine
{
get { return GetValue<Machine>(ControlledMachineProperty); }
private set { SetValue(ControlledMachineProperty, value); }
}
public static readonly PropertyData ControlledMachineProperty = RegisterProperty("ControlledMachine", typeof(Machine));
public override string Title { get { return "Set Machine state"; } }
public Command StartMachine { get; private set; }
public Command PauseMachine { get; private set; }
public Command StopMachine { get; private set; }
private void OnStartMachineExecute()
{
_state = Machine.MachineState.RUNNING;
//ControlledMachine.SecondState = Machine.MachineState.RUNNING;
}
private void OnPauseMachineExecute()
{
_state = Machine.MachineState.PAUSED;
//ControlledMachine.SecondState = Machine.MachineState.PAUSED;
}
private void OnStopMachineExecute()
{
_state = Machine.MachineState.STOPPED;
//ControlledMachine.SecondState = Machine.MachineState.STOPPED;
}
}
}
Я не понимаю, почему я должен делать это таким образом и почему это не работает так, как я его реализовал , Во всяком случае, я заставил его вести себя так, как ожидалось, исходя из информации выше. Я создал копию свойств, когда диалог создается как начальное состояние. Затем в методе «Сохранить» я перехожу через словарь свойств, который ищет тот, который изменил этот диалог, и посмотрел, изменилось ли оно. Если он изменился, я создаю ActionUndo и добавляю его в пакет. Наконец, я добавляю пакет в службу Memento. Уверен, могу написать сообщение об этом. Но что такое PR? –
PR - запрос Pull –
aah, вы имеете в виду интегрировать его в ModelBase и ViewModelBase. Думаю, мне нужно было бы лучше понять Catel, но может попробовать, и если вам это нравится, примите это. –