網站首頁 編程語言 正文
一個比較常見的改進用戶體驗的方案是用Redo/Undo來取代確認對話框,由于這個功能比較常用,本文簡單的給了一個在C#中通過Command模式實現Redo/Undo方案的例子,以供后續查詢。
class Program
{
static void Main(string[] args)
{
var cmds = new CommandManager();
while (true)
{
var key = Console.ReadKey(true);
if (key.KeyChar >= '0' && key.KeyChar <= '9')
{
cmds.DoNewCommand(key.KeyChar.ToString(), () => Console.WriteLine("process " + key.KeyChar), () => Console.WriteLine("redo " + key.KeyChar));
}
else
{
if (key.Modifiers.HasFlag(ConsoleModifiers.Control) && (key.Key == ConsoleKey.Z))
cmds.UnDo();
else if (key.Modifiers.HasFlag(ConsoleModifiers.Control) && (key.Key == ConsoleKey.Y))
cmds.ReDo();
}
}
}
}
class CommandManager
{
#region Command定義
public class Command
{
string name;
Action action;
Action unDoAction;
internal Command(string name, Action action, Action unDoAction)
{
this.name = name;
this.action = action;
this.unDoAction = unDoAction;
}
internal void Do() { action(); }
internal void UnDo() { unDoAction(); }
public override string ToString()
{
return name.ToString();
}
}
#endregion
public Stack<Command> ReDoActionStack { get; private set; }
public Stack<Command> UnDoActionStack { get; private set; }
public CommandManager()
{
ReDoActionStack = new Stack<Command>();
UnDoActionStack = new Stack<Command>();
}
public void DoNewCommand(string name, Action action, Action unDoAction)
{
var cmd = new Command(name, action, unDoAction);
UnDoActionStack.Push(cmd);
ReDoActionStack.Clear();
cmd.Do();
}
public void UnDo()
{
if (!CanUnDo)
return;
var cmd = UnDoActionStack.Pop();
ReDoActionStack.Push(cmd);
cmd.UnDo();
}
public void ReDo()
{
if (!CanReDo)
return;
var cmd = ReDoActionStack.Pop();
UnDoActionStack.Push(cmd);
cmd.Do();
}
public bool CanUnDo { get { return UnDoActionStack.Count != 0; } }
public bool CanReDo { get { return ReDoActionStack.Count != 0; } }
//public IEnumerable<Command> Actions { get { return ReDoActionStack.Reverse().Concat(UnDoActionStack); } }
}
原理很簡單,通過Command模式把每一步操作封裝成一個可undo的命令(包含do和redo兩個操作)。并將每一步操作執行后用棧保存起來,undo的時候就以此將Command依次出棧,并執行undo操作。(從某種意義上來說,redo就是undo操作的undo)
上面的代碼已經實現了基本的Undo/Redo功能,但實際使用的時候還是有一些細節需要考慮的:如undo或redo時失?。⊕伄惓#┑奶幚淼?。由于這些細節方面的處理方式不盡相同,本文只是實現一個基本框架,以備后續使用時參考,并不想把它弄的過于復雜。
這種方式比較簡單,幾乎每種語言都可以輕易的寫出這種方式下的實現。但通過這種Command封裝的方式實現的也有一些限制,使用的時候需要注意:
- 每一步操作都需要封裝成command命令
- 每一步操作都是可逆的
- 當命令過多的時候需要考慮commandlist的內存占用和命令查詢時的性能問題
原文鏈接:https://www.cnblogs.com/TianFang/archive/2010/10/05/1844385.html
相關推薦
- 2022-08-30 啟動Activity但是不顯示界面
- 2022-03-22 詳解jQuery的核心函數和事件處理_jquery
- 2022-04-28 Python可視化學習之seaborn繪制線型回歸曲線_python
- 2023-12-25 Spring 之 @Cacheable 緩存使用教程
- 2022-08-21 Python列表去重的幾種方法整理_python
- 2022-10-14 WebSecurityConfigurerAdapter已棄用
- 2023-12-18 Jedis和springboot集成redis
- 2023-06-16 GO的鎖和原子操作的示例詳解_Golang
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支