它們就表示“撤銷”與“反撤銷”。在程序中,這種功能通常是使用Command模式實現(xiàn)的,本文也不例外。首先抽象定義Command,使用ICommand接口:
{
void Excute() ;
}
可撤銷的命令也是一種命令,所以從ICommand繼承:
{
void Undo() ;
}
為了實現(xiàn)撤銷功能,我們需要一個堆棧來記錄所有已執(zhí)行的可撤銷命令,為了實現(xiàn)反撤銷的功能,同樣,我們也需要一個堆棧來記錄所有已撤銷的命令。這個職責(zé)是由ICommandManager接口提供:
{
void ExcuteCommand(ICommand command) ;
void Undo() ;
void ReverseUndo() ;//反撤銷
//以下事件可用于控制撤銷與反撤銷圖標(biāo)的啟用
event CbSimpleBool UndoStateChanged ; //bool參數(shù)表明當(dāng)前是否有可撤銷的操作
event CbSimpleBool ReverseUndoStateChanged ; //bool參數(shù)表明當(dāng)前是否有可反撤銷的操作
}
現(xiàn)在,我們來詳細(xì)分析一下,撤銷命令堆棧和反撤銷命令堆棧在何時Push命令對象、又在何時Pop命令對象:
(1)當(dāng)執(zhí)行完任何一個command后,reverseUndo堆棧清空
(2)當(dāng)執(zhí)行完一個不可撤銷的command后,undo堆棧清空
(3)當(dāng)執(zhí)行完一個可撤銷的command后,將其壓入undo堆棧
(4)當(dāng)撤銷一個command后,將其轉(zhuǎn)移到reverseUndo堆棧
基于此,我們就可以實現(xiàn)ICommandManager:
{
private Stack undoStack = new Stack() ;
private Stack reverseStack = new Stack() ;
public event CbSimpleBool UndoStateChanged ;
public event CbSimpleBool ReverseUndoStateChanged ;
public CommandManager()
{
this.UndoStateChanged += new CbSimpleBool(CommandManager_UndoStateChanged);
this.ReverseUndoStateChanged += new CbSimpleBool(CommandManager_UndoStateChanged) ;
}
private void CommandManager_UndoStateChanged(bool val)
{
}
#region ICommandManager 成員
public void ExcuteCommand(ICommand command)
{
command.Excute() ;
this.reverseStack.Clear() ;
if(command is IBackableCommand)
{
this.undoStack.Push(command) ;
}
else
{
this.undoStack.Clear() ;
}
this.UndoStateChanged(this.undoStack.Count > 0) ;
}
public void Undo()
{
IBackableCommand command = (IBackableCommand)this.undoStack.Pop() ;
if(command == null)
{
return ;
}
command.Undo() ;
this.reverseStack.Push(command) ;
this.ReverseUndoStateChanged(this.reverseStack.Count > 0) ;
}
public void ReverseUndo()
{
IBackableCommand command = (IBackableCommand)this.reverseStack.Pop() ;
if(command == null)
{
return ;
}
command.Excute() ;
this.undoStack.Push(command) ;
this.UndoStateChanged(this.undoStack.Count > 0) ;
this.ReverseUndoStateChanged(this.reverseStack.Count > 0) ;
}
#endregion
}
本文介紹的撤銷與反撤銷功能是與應(yīng)用無關(guān)的,所以可以在不同的應(yīng)用中復(fù)用,你只需要根據(jù)你自己的應(yīng)用需求來實現(xiàn)對應(yīng)的ICommand接口和IBackableCommand接口就可以立即使用撤銷與反撤銷功能了。