我有我的WinForms應用程序的一些不錯的,工作的編輯撤消功能。它使用CommandStack
類,這是兩個Stack<IStateCommand>
s(一個用於撤消,一個用於重做)。每個命令都有一個Execute
和一個Undo
方法,並且對象本身有一個事件,當堆棧被更改時會觸發。C#檢測,如果電話都是在相同的UI操作
如果LogCommand方法是從其自己的Undo函數中調用的,並因此將其添加到重做堆棧而不是撤消堆棧,則CommandStack
也會生效。這是通過簡單地將當前ManagingThreadId
添加到List<int>
對象中完成的,然後在撤消命令完成後將其刪除(與使用堆棧跟蹤相反,我認爲這會比較慢並且有點髒)。
在我的應用程序中有很多不同的命令,所以這個公式有一定的難度,因爲它需要我幾天的時間來重做所有這些實現。
這個唯一的問題,目前,內也有一些UI事件調用其他UI事件,這兩者的身份登錄到IStateCommand
撤銷歷史。有沒有在C#中的任何方式,我可以檢測是否LogCommand功能已經從相同的UI事件(點擊,的DragDrop,的SelectedIndexChanged,框TextChanged等),然後我可以將命令組合成一個命令調用(使用我CommandList
類,這也繼承了IStateCommand
)?
我想保存時撤消事件被稱爲當前時間,那麼如果下一個命令比x毫秒以後登錄以下,將它們組合起來的歷史,但是這似乎有點草率。我也考慮過搜索堆棧跟蹤,但我不知道要查找根UI事件要尋找什麼,也不知道我是否會告訴一個按鈕單擊之間的差異,然後點擊不同的點擊按鈕。
這也可能是讓你知道,所有這些命令正在從事件處理(從自定義用戶控件主要來自事件)UI線程調用。使用另一個線程的應用程序的唯一部分在記錄撤消歷史記錄後,在大多數UI事件之後運行。
謝謝!
排序版
相同的方法正在從相同的UI事件調用兩次(例如,的MouseUp,的DragDrop)。第二次調用此方法時,如何檢查它是否已被相同的UI事件調用一次?
編輯:該解決方案(在某種程度上)
這是一個有點髒的一個,因爲我不必完全重新編寫這個系統的時間。不過,我已經以這樣的方式實現了它,使得選項在未來不會太髒。
該解決方案是基於艾爾諾對他的答覆意見(所以我將迎來自己的答案被接受),在那裏他建議添加的參數之一。我在CommandStack
類LogCommand(IStackCommand, string)
中爲我的LogCommand(IStackCommand)
方法增加了另一個過載。字符串是爲每個命令存儲的actionId,如果該字符串與最後一個字符串相同,則組合該命令。這給出了通過每個事件並給出唯一ID的選項。
然而,髒部分 - 得到它的工作之前,我們必須表現出客戶端,actionId
默認爲System.Windows.Forms.Cursor.Position.ToString()
,哎喲!由於UI線程正在執行時遊標位置不會更改,因此它會合並每個命令。它實際上甚至結合了TextChanged命令(只要它們不移動它們的鼠標!)
似乎最好的解決方案,爲每個基本方法調用創建一個堆棧,並有任何結果方法調用寫入。然後,您可以將這些堆棧添加到主撤銷/重做堆棧。 –
我不確定我是否理解,或者我的問題還不夠清楚:/ IStateCommand不調用其他IStateCommand,如果這就是你的意思。一個UI事件是a)記錄一個IStateCommand,和b)調用另一個動作,最終記錄另一個IStateCommand。 – Connell
我已經有了一個CommandList,它也繼承了IStateCommand,並且可以同時執行/撤銷多個命令。你會如何建議我找到基礎方法調用? – Connell