【发布时间】:2014-11-01 20:16:35
【问题描述】:
在使用对话框时,我无法让 Undo 和 Redo 正常运行。
我有一个简单的模型,其属性指示对象的状态(running、paused、stopped)可以通过对话框进行更改。发生的情况是,我的撤消队列中似乎没有执行任何操作,或者撤消将对象恢复到中间状态。
模型对象在构造函数中注册到 memento。该对话框具有三个单选按钮,每个按钮代表三种不同状态之一。每个单选按钮都绑定到一个命令。每个命令都会更改属性。我尝试了两种不同的方法,每个命令直接在对象中设置属性,或者每个命令在调用时为视图模型设置一个实例变量,然后我使用保存事件来修改对象。
如果使用第一种方法,如果用户在单击对话框中的“确定”之前单击了多个单选按钮,则每个属性更改都将放在“撤消”队列中。试图通过将整个对话框包装成批处理来解决该问题,但这会导致状态更改撤消,对象将恢复到最后一个之前的状态,即如果在对话框打开之前属性设置为stopped,并且用户按下暂停单选按钮,然后启动一个,最后确定,撤消将属性设置为paused,而不是预期的stopped。
如果使用第二种方法,用户打开对话框,将状态更改为paused,在对话框中单击“确定”,撤消/重做的行为与预期相同,但如果再次打开对话框并选择“取消”,则会添加更多操作到 Undo 队列,即用户必须单击 Undo 两次才能回到初始的stopped-state。
所以我的问题是如何正确实施以获得预期的行为;每个对话交互都可以撤消,而不是对话中的每个交互?
这是 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;
}
}
}
【问题讨论】: