2009-12-02 149 views
3

我想知道如何使用TextArea實現撤消重做功能。我已經有了一個undoredo框架功能,現在我有兩個問題。在TextArea中實現撤銷/重做

  1. 什麼時候開始/停止一個新的撤消/重做命令,例如當用戶點擊撤消時,我要走多遠。
  2. 如何在一個正常的文本區域

我的想法實現這一(1): 我想,我應該創建一個新的撤銷命令,當任何東西,但alphanumber +空間被擊中。要做到這一點,我會使用keyDown事件,並測試密鑰是否爲阿爾法如果不是,我會重置命令。

聽起來不錯?

回答

1

1.當我開始/停止一個新的撤消/重做命令時,例如,當用戶點擊撤消時,我要走多遠。

您是否認爲您的用戶需要撤消多個步驟?如果是這樣,那麼你可能想要有一個歷史記錄(例如Paint .NET)並允許無限撤銷。否則,請記住最近執行的操作。

2

收聽keydown事件將錯過用戶用鼠標進行的任何文本編輯(剪切/複製/粘貼)。

我認爲一個更好的方法是聽控件上的「更改」事件(只要內容通過用戶輸入發生變化就會觸發),並且只是推動控件的全部內容(它的'text'或'htmlText '屬性)與每個更改事件轉換爲一個撤銷緩衝區(一個字符串數組)。我假設內存使用率不是問題(它可能不是,取決於控件內容的預期大小和撤消級別的數量)。

這樣,您只需將撤消緩衝區中相應的控制狀態(通過數組上下移動)複製到控件中即可實現撤消/重做。

'正確'的方法是跟蹤實際的編輯,而且會更加複雜。

1

1.)您應該監聽TextField上的Event.CHANGE事件,並在每次觸發事件時創建一個歷史記錄步驟。歷史步驟包含您的兩個值:舊的和新的。 Old是更改前TextField的值,new是更改後的值。

2.)您的歷史記錄是一系列操作,或者您可以使用Memento Pattern。我認爲行動更容易使用。歷史動作有兩種方法,undo()和redo()。所以在undo()中你必須說textField.text = oldContent,在redo()方法中你說textField.text = newContent。您的歷史記錄還需要一個指向當前操作的指針。

3.)讓它更好一點。你不應該只聽Event.CHANGE,而是聽第一個CHANGE,然後聽那個TextField的下一個FOCUS_OUT。在這種情況下,只有在停止編輯TextField時纔會創建歷史記錄步驟。但它取決於你的TextField以及你想如何分配歷史步驟。多行TextField不應僅在FOCUS_OUT上創建歷史步驟:)