使用对话框时,我无法让 Undo 和 Redo 正常运行。
我有一个简单的模型,其属性指示对象的状态(running
, paused
, stopped
),可以通过对话框进行更改。发生的情况是,我的撤消队列中似乎没有执行任何操作,或者撤消将对象恢复到中间状态。
模型对象在构造函数中用 memento 注册。该对话框具有三个单选按钮,每个按钮代表三种不同状态之一。每个单选按钮都绑定到一个命令。每个命令都会更改属性。我尝试了两种不同的方法,每个命令直接在对象中设置属性,或者每个命令在调用时为视图模型设置一个实例变量,然后我使用保存事件来修改对象。
如果使用第一种方法,如果用户在单击对话框中的“确定”之前单击了多个单选按钮,则每个属性更改都将放在“撤消”队列中。试图通过将整个对话框包装成一个批处理来解决这个问题,但这会导致状态更改撤消,对象将恢复到最后一个之前的状态,即如果属性设置为stopped
在对话框打开并且用户按下之前暂停单选按钮,然后启动一个,最后确定,撤消会将属性设置为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;
}
}
}