onExit 事件是否能(在父系的form下指令)暫時取消之後再加回來 |
答題得分者是:jow
|
shininggod
一般會員 發表:16 回覆:20 積分:17 註冊:2009-05-13 發送簡訊給我 |
我想的到的方案是用一個全預變數來判斷要不要跑 onExit, 可是這樣要每個onexit都要另外寫orz...
例如一個TDBedit: 現在是說,因為使用者在查資料的時候要copy上面的字,所以不能給他 enable := false 鎖住 問題是他copy 完滑鼠一點別的就會觸發 onexit, 但是他在加/改資料的時候 onexit 又要能跑好判斷資料是不是可接受的形式. 在知道procedure 名稱的時候是可以用 查詢時 TDbMyEdit.OnExit := nil; 新增/修改 TDbMyEdit.OnExit := TDbMyEditonExit; 這樣加的回來 可是這個 form 是繼承來的,在父系跑全域 compenments / Controls 設定時能不能就做這種事? 父系不知道後代上面的東西名稱orz.... 查詢時拿掉容易 for vJ := 0 to myPageControl.Pages[0].ControlCount - 1 do begin if (inPC.Pages[0].Controls[vJ] is TDBEdit) then TDBedit(inPC.Pages[0].Controls[vJ]).OnExit := nil; end; 要加回來的時囧到Orz.. 原本以為用self, 配一個 FindProcedure 之類的 問題是根本沒有 FindProcedure 這東西囧rz, 估狗也估不到啥... 試驗: TDBedit(inPC.Pages[0].Controls[vJ]).OnExit := self.FindComponent(inPC.Pages[0].Controls[vJ]).name).onexit; 當然,無效orz 難道要弄一個 TNotifyEvent 的 set 存起來再丟回去 Orz? |
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
父親是文盲,辛苦工作送兒子去美國讀書,所以兒子比父親多了英語這項能力。如今兒子在英語應用上遇到問題,父親是無法直接給予幫助的,還是要靠兒子自行努力。我想這是(OO)不可違逆的法則吧。
換個角度想,若父親本身就具備英語能力,那所有後代子孫也會有。父親一變後代也跟著變。是否可以把你要的 OnExit Event 也寫一份在父類別上,讓所有子類別繼承這個 method (Overriding) 進而達到由父類別可以控制所有子類別的需求呢? 純以 OO 概念提出一些想法參考~ ===================引 用 shininggod 文 章=================== 可是這個 form 是繼承來的,在父系跑全域 compenments / Controls 設定時能不能就做這種事? 父系不知道後代上面的東西名稱orz....
編輯記錄
TWY 重新編輯於 2010-02-26 09:07:11, 註解 無‧
|
shininggod
一般會員 發表:16 回覆:20 積分:17 註冊:2009-05-13 發送簡訊給我 |
|
jow
尊榮會員 發表:66 回覆:751 積分:1253 註冊:2002-03-13 發送簡訊給我 |
[code delphi] unit fMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Mask, DBCtrls; type THandlerObj = class Name: string; Handler: TNotifyEvent; end; TForm1 = class(TForm) DBEdit1: TDBEdit; DBEdit2: TDBEdit; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FList: TStringList; public procedure SwitchOnExitEventHandler(TURN_ON: Boolean); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var I: Integer; O: TDBEdit; P: THandlerObj; begin FList := TStringList.Create; FList.Sorted := True; for I := 0 to ComponentCount-1 do begin if Components[I] is TDBedit then begin O := TDBEdit(Components[I]); if Assigned(O.OnExit) then begin P := THandlerObj.Create; P.Name := O.Name; P.Handler := O.OnExit; FList.AddObject(P.Name,P); end; end; end; end; procedure TForm1.FormDestroy(Sender: TObject); var I: Integer; begin for I := 0 to FList.Count-1 do FList.Objects[I].Free; FreeAndNil(FList); end; procedure TForm1.SwitchOnExitEventHandler(TURN_ON: Boolean); var I,Index: Integer; O: TDBEdit; begin case TURN_ON of False: begin for I := 0 to ComponentCount-1 do if Components[I] is TDBEdit then TDBEdit(Components[I]).OnExit := nil; end; else begin for I := 0 to ComponentCount-1 do if Components[I] is TDBEdit then begin O := TDBEdit(Components[I]); if FList.Find(O.Name,Index) then O.OnExit := THandlerObj(FList.Objects[Index]).Handler; end; end; end; end; end. [/code] 謹供參考...^_^ |
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
|
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
呵呵,看來 jow 大大的確是這樣做的喔,不過碼寫的工整潔明令人閱讀愉快。
我在想,若把 jow 的 Code 寫在你的父類別, SwitchOnExitEventHandler 改宣告 protedted 讓子類別都可呼叫,或許可以輕鬆漂亮的解決你的困擾,你可以試著想看看。 ===================引 用 shininggod 文 章=================== 難道要弄一個 TNotifyEvent 的 set 存起來再丟回去Orz? |
TWY
高階會員 發表:2 回覆:133 積分:152 註冊:2009-09-02 發送簡訊給我 |
剛有時間寫了一個小範例,不知道能否幫得上忙。(若你問題有因此獲得解決並欲給分,請給 jow,我是抄他的來改的 )
unFather.pas 是父類別 Form, unSon.pas 繼承自 unFather。主要程式碼都在 unFather.pas,而開關 OnExit Event 控制權仍在各子類別(應該是合理的),不過已經簡化、彈性化很多了。 [code delphi] unit unFather; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TfrmFather = class(TForm) Memo2: TMemo; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private declarations } g_slEventContainer : TStringList; public { Public declarations } protected procedure _SwitchOnExitEvent(isWork : Boolean); end; var frmFather: TfrmFather; implementation {$R *.dfm} type TMyEventObj = class Name : String; EventReference : TNotifyEvent; end; procedure TfrmFather.FormCreate(Sender: TObject); var i : Integer; myEventObj : TMyEventObj; begin g_slEventContainer := TStringList.Create; g_slEventContainer.Sorted := True; for i := 0 to ComponentCount-1 do begin if (Components[i] is TEdit) and Assigned( (Components[i] as TEdit).OnExit ) then begin myEventObj := TMyEventObj.Create; myEventObj.Name := (Components[i] as TEdit).Name; myEventObj.EventReference := (Components[i] as TEdit).OnExit; g_slEventContainer.AddObject(myEventObj.Name,myEventObj); end; end; end; procedure TfrmFather.FormDestroy(Sender: TObject); var i : Integer; begin for i := 0 to g_slEventContainer.Count-1 do g_slEventContainer.Objects[i].Free; FreeAndNil(g_slEventContainer); end; procedure TfrmFather._SwitchOnExitEvent(isWork: Boolean); var i : Integer; begin for i := 0 to g_slEventContainer.Count-1 do begin if isWork then (FindComponent(TMyEventObj(g_slEventContainer.Objects[i]).Name) as TEdit).OnExit := TMyEventObj(g_slEventContainer.Objects[i]).EventReference else (FindComponent(TMyEventObj(g_slEventContainer.Objects[i]).Name) as TEdit).OnExit := Nil; end; end; end. [/code] [code delphi] unit unSon; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, unFather, StdCtrls; type TfrmSon = class(TfrmFather) Memo1: TMemo; Edit1: TEdit; Edit2: TEdit; Button1: TButton; Button2: TButton; procedure Edit1Exit(Sender: TObject); procedure Edit2Exit(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var frmSon: TfrmSon; implementation {$R *.dfm} procedure TfrmSon.Edit1Exit(Sender: TObject); begin inherited; Memo1.Lines.Add('Edit1.OnExit'); end; procedure TfrmSon.Edit2Exit(Sender: TObject); begin inherited; Memo1.Lines.Add('Edit2.OnExit'); end; procedure TfrmSon.Button1Click(Sender: TObject); begin inherited; _SwitchOnExitEvent(True); //讓所有 TEdit 恢復 OnExit Event end; procedure TfrmSon.Button2Click(Sender: TObject); begin inherited; _SwitchOnExitEvent(False); //讓所有 TEdit 失去 OnExit Event end; end. [/code] |
shininggod
一般會員 發表:16 回覆:20 積分:17 註冊:2009-05-13 發送簡訊給我 |
除非 cc 公司肯弄個 findprocedure 的 function , 靠這個大概無望了XD
-------------------------------------------------------------------------------------------------- 先存起來再叫出來用是可以.... 我擔心的是假如有一大票onExit, 那每次都要繞loop一次..哪種神奇超慢主機會不會就被.... -------------------------------------------------------------------------------------------------- 我原來的"想法"是, 這東西在create 完之後, 他的 event 都已經建立完 存在, 就算我換掉他, 應該只是 pointer 指向換位置, 原本的東西應該還是存在, 所以再指回去應該就可以用了 不過這想法對不對都是問題Orz ------------------------------------------------------------------------------------------------- jow大勾的code真是漂亮, 我的code亂七八糟根本不敢貼上來(核爆), |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |