|
一個友好的用戶界面,必須具有下拉菜單,彈出菜單,工具條和快捷鍵。同樣一個功能,程序員可能要提供幾種操作方式,如文本拷貝,菜單命令&
Copy,快捷鍵Ctrl+C,工具條上的拷貝按鈕,都是程序員提供給用戶的操作,可以大大方便了不同層次的用戶。但是,多增加一種操作方式,就意味著增
加響應事件的代碼,還有,實現統一功能的多個操作必須一致,如剪切板上不為空的時候,菜單命令,快捷鍵,按鈕,都是可以選擇的Enabled狀態,而剪切
板上沒有內容時,這些構件的Enabled狀態都為假。當然,如果不集中控制這些細節的話,實現相同功能的構件要一致,必須多增加代碼,控制較為復雜。 Action
就是將實現某個功能的細節統一管理起來,如Caption, Checked, Enabled, HelpContext, Hint,
ImageIndex, ShortCt, Visible,
onExecute等屬性和事件。程序員設置Action屬性的同時,還要實現執行Action的代碼onExecute。定義了Action后,將其連
接到一個菜單項,或者按鈕上時,Action定義的屬性和OnExecute事件,馬上取代了原來的設置,并且建立了連接。通過這個連接,當Action
的屬性發生變化時,如Enabled發生變化,那么與之連接的構件屬性都會自動更新;反過來,當構件對應的事件被執行時,Action的
onExecute也被調用。 8.1.2 Action 和ActionList Action是定義了最小的功能單位,使用它來在不同構件間,達到代碼集中管理。表4-12定義了Action的一些屬性: ActionList
是將多個Action統一管理的構件,在窗體設計階段,使用它的彈出菜單,可以增減Action和定義Action的屬性。它本身的屬性Image連接了
一個TImageList,指出它所包含的Action使用那個TImageList來定義ImageIndex。ActionLink是一個看不見的構
件,但是它是負責構件和Action之間建立連接的。 表 4-12 Action屬性和事件 屬性和事件 具體功能 Caption 標題,可用于菜單項,ToolButton等。 Category 分類 Checked 設置選擇狀態,用于菜單項 Enabled 設置可用狀態,用于與之連接的所有構件 HelpContext 幫助的索引項,用于與之相連的所有構件 Hint 智能感知,設置提示內容 ImageIndex 設置菜單項和按鈕上的圖片 Visible 指示與之連接的構件可否顯示 ShortCut 設置菜單項的快捷鍵。 OnExecute 執行此Action的代碼 OnHint 當被感知的構件顯示Hint時調用的代碼 OnUpdate 當Action更新構件的屬性時調用的代碼 //////////// 我們先來認識TActionList。TActionList 是從TCustomAction中繼承來的,由它管理定義好的Action,是程序員在對Action編程的接口。 新
建一個工程文件,在主窗體上增加一個TActionList,一個TMemo,一個TImageList,幾個按鈕,幾個菜單項。雙擊
TActionlist,會出現它的編輯界面。再單擊右鍵選擇New standard
action,顯示出預定義的Action類別,屬性Category是用來表明Action所屬類別,我們可以根據需要選擇具體的類別,如圖4-10所
示,我們引入了文件操作的一些標準Action。 這里所列的Action,大部分屬性已經定義好了,就是說只要把他們添加到ActionList中,就可以使用。同樣的,也可以新建Action,在Category屬性中加上自己定義的名字,之后再添加新的Action 。 8.2.2 連接Action 定義了Action后,不與菜單項和按鈕連接,是不能使用的,也沒有達到程序功能集中實現和管理。使用對象觀察器,看看我們剛剛選擇的菜單項和按鈕上是否有屬性Action。 在
這些構件的Action屬性內,選擇一個Action之后,構件本身的很多屬性都隨著Action定義的屬性發生了變化,例如菜單項的Caption與
Action的屬性Caption就一致了,構件的屬性Name和Tag是不隨著改變的。連接后,Action的屬性值被拷貝到所連接構件的相應屬性上,
這種連接是動態地,當Action的屬性值發生變化時,自動更新所聯系的構件。 注意:如果使用的是一個TToolButton 或著是菜單項,必須自己設置與它相聯系的Images屬性,雖然構件的ImageIndex屬性已經動態的同Action相連接,但是屬性Images并未自動連接。 繼續本節的例子,通過設置菜單項和按鈕的Action屬性,完成Action的連接。 8.2.3 處理Action 處
理Action的代碼可放置在Action的onExecute事件,也可以集中放置在ActionList的onExecuteAction中,還可以
更集中的放置在Application的onExecuteAction事件中。改變了以往每個構件都必須對應事件的做法,程序設計上更系統化。 在本節的例子中,編寫某幾個Action的onExecute方法。如FileOpenCmd的onExecute事件如下: if OpenDialog.Execute then Memo1.LoadFromFile(OpenDialog.FileName); 8.2.3 更新Action屬性 Action
的事件有OnExecute和OnUpdate,OnExecute事件在控制被觸發時響應,比如說按鈕被按下,菜單被按下,而OnUpdate事件是在
應用程序空閑時被調用,用來更新Action的屬性。ActionList 中也有OnUpdate,
可以用作設置菜單或者按鈕的可選等屬性使用。如下例,這個例子來自于$Delphi\Demos\RichEdit\Richedit.Dpr程序,有興
趣的讀者可查看一下,以便更了解Action。 1 procedure TMainForm.ActionList2Update(Action: TBasicAction; var Handled: Boolean); 2 begin 3 EditCutCmd.Enabled := Editor.SelLength > 0; 4 EditCopyCmd.Enabled := EditCutCmd.Enabled; 5 if Editor.HandleAllocated then 6 begin 7 EditUndoCmd.Enabled := Editor.Perform(EM_CANUNDO, 0, 0) <> 0; 8 EditPasteCmd.Enabled := Editor.Perform(EM_CANPASTE, 0, 0) <> 0; 9 end; 10 end; 當應用程序空閑時,就執行這段代碼,首先檢查是否有被選定的文本,如果有則將Cut和Copy的Enabled屬性設為True;當前控制是Editor時,設置Undo和Paste屬性,Perfom是構件向自身發送消息的方法。 Delphi
已經定義了一些標準的Action,這些Action實現的功能和VCL代碼已經結合起來。所以,程序員可以直接使用,有些Action甚至不需要定義
onExecute事件。如Cut,Copy,Paste等剪切板操作,Cancel,Delete,Edit,First,Insert,Last,
Next,Prior,Post,Refresh等數據導航功能,Arrange,Cascade,Close,MinimizeAll,
TileHorizontal等窗口排布功能。
|
|