如鵬網(wǎng) 大學(xué)生計(jì)算機(jī)學(xué)習(xí)社區(qū)

          CowNew開源團(tuán)隊(duì)

          http://www.cownew.com 郵件請聯(lián)系 about521 at 163.com

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            363 隨筆 :: 2 文章 :: 808 評論 :: 0 Trackbacks
          ?

          六、控件手拉手――控件關(guān)聯(lián)的實(shí)現(xiàn)

          控件的關(guān)聯(lián)在Delphi中也是很常見的,我們可以設(shè)定一個控件的某個屬性指向另一個控件。比如我們在窗體上放上Tedit,TpopupMenu兩個控件,然后設(shè)定TeditPopupMenu屬性為TpopupMenu控件,運(yùn)行后在Tedit點(diǎn)擊右鍵就會彈出剛才設(shè)定的那個TpopupMenu菜單,也就是說Tedit,TpopupMenu聯(lián)手完成了任務(wù)。再比如TDBEdit控件的DataSource屬性就可以指向一個TdataSource控件,這樣就可以在TDBEdit控件中顯示TdataSource輸出的某個字段的值了。

          ? 下面我們將寫一個簡單的實(shí)現(xiàn)控件關(guān)聯(lián)的控件。這個控件派生于Tedit,它可以與一個Tlabel控件關(guān)聯(lián),在控件的編輯框中輸入文字時,與它關(guān)聯(lián)的Tlabel控件的文字將隨著它而變化。代碼如下:

          unit MyEdit;

          interface

          uses

          ? SysUtils, Classes, Controls, StdCtrls;

          type

          ? TMyEdit = class(TEdit)

          ? private

          ??? FLinkLabel: TLabel;

          ??? procedure FSetLinkLabel(AValue: TLabel);

          ? protected

          ??? procedure Notification(AComponent: TComponent;Operation: TOperation);

          ????????? override;

          ??? procedure Change;override;

          ? public

          ? published

          ??? property LinkLabel: TLabel read FLinkLabel write FSetLinkLabel;

          ? end;

          ?

          procedure Register;

          ?

          implementation

          procedure Register;

          begin

          ? RegisterComponents('Linco', [TMyEdit]);

          end;

          procedure TMyEdit.Change;

          begin

          ? inherited;

          ? if LinkLabel <> nil then

          ??? LinkLabel.Caption := Text;

          end;

          ?

          procedure TMyEdit.FSetLinkLabel(AValue: TLabel);

          begin

          ? FLinkLabel := AValue;

          ? if AValue <> nil then

          ??? FLinkLabel.FreeNotification(self);

          end;

          ?

          procedure TMyEdit.Notification(AComponent: TComponent;

          ? Operation: TOperation);

          begin

          ? inherited;

          ? if (Operation = opRemove) and (AComponent = LinkLabel) then

          ??? LinkLabel := nil;

          end;

          end.

          代碼解釋:

          1)、我們只要將控件的任意一個屬性的類型設(shè)定為另外一個控件的類名稱,那么我們就可以在控件的Object Inspector中將這個屬性指向那個控件(或那個控件的派生控件)的一個實(shí)例。比如本例中我們增加了LinkLabel屬性,它的類型為 Tlabel,所以我們就可以把LinkLabel屬性指向一個標(biāo)簽控件。

          2)、請注意FsetLinkLabel中的這段代碼:

          ?if AValue <> nil then

          FLinkLabel.FreeNotification(self);

          如果我們將控件關(guān)聯(lián)屬性指向了一個控件,可是后來又將被指向的控件刪除了,那么我們的控件關(guān)聯(lián)屬性是不會自動刪除的,這樣就會造成控件關(guān)聯(lián)屬性指向的控件不存在的現(xiàn)象。我們必須自動感知被關(guān)聯(lián)控件的刪除并重新設(shè)定控件關(guān)聯(lián)屬性為不指向任何控件,這樣就避免了錯誤的發(fā)生。

          FLinkLabel.FreeNotification(self);的作用就是這樣的。它調(diào)用控件的FreeNotification方法(在Tcomponent中定義)向被指向的控件注冊一個“消息”,當(dāng)被指向控件被刪除時,會向所有向他注冊的控件發(fā)送一個它被刪除的消息,此時向他注冊的控件就會觸發(fā)Notification方法,這樣我們就可以自動感知被指向控件的狀態(tài)了。這是設(shè)計(jì)模式中Observer(觀察者)模式的典型應(yīng)用。

          既然向他注冊的控件就會觸發(fā)Notification方法,我們就覆蓋父類的Notification方法,寫出如下的代碼:

          ? if (Operation = opRemove) and (AComponent = LinkLabel) then

          ??? LinkLabel := nil;

          這句話的意思是:如果控件被刪除并且被刪除的控件(因?yàn)槲覀兊目丶赡芟蚨鄠€控件注冊了消息)是LinkLabel,那么我們就設(shè)定LinkLabel屬性不指向任何控件。

          3)覆蓋父類的Change調(diào)度方法。在此方法里為連接的LinkLabelCaption賦值就達(dá)到我們的目的了。

          思考題:

          1、做一個Label控件,給它增加一個DataSource屬性,該屬性可以指向一個TdataSource類型的控件,它有一個GetRecordCount方法。當(dāng)調(diào)用此方法時,就在Label控件中顯示這個DataSource對應(yīng)的數(shù)據(jù)集中的記錄的條數(shù)。

          posted on 2005-10-21 23:34 CowNew開源團(tuán)隊(duì) 閱讀(2144) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 金门县| 新民市| 辽宁省| 嵊州市| 信宜市| 罗田县| 巨野县| 沈阳市| 大悟县| 湛江市| 八宿县| 苏州市| 永春县| 南安市| 清丰县| 喀什市| 阿拉善盟| 宣恩县| 滕州市| 阜新市| 房产| 年辖:市辖区| 临颍县| 台州市| 堆龙德庆县| 准格尔旗| 姜堰市| 榕江县| 夏邑县| 加查县| 呼玛县| 台中县| 晋江市| 绿春县| 昆山市| 莲花县| 全州县| 遵义市| 涿鹿县| 孟连| 乌拉特后旗|