2010-11-22 47 views
3

我有一個自TGraphicControl降序的自定義Delphi組件。它的類被聲明如下:自定義Delphi組件的Redeclare Width屬性

TMyLabel = class(TGraphicControl) 
private 
    ... 
protected 
    ... 
public 
    ... 
published 
    property Height; 
    property Width write SetWidth; 
    ... 
end; 

SetWidth的實施進一步在於:

procedure TMyLabel.SetWidth(const Value: Integer); 
begin 
    if (Value >= 0) and (Value <> Width) 
    then begin 
    inherited Width := Value; 
    // Do some other stuff 
    ... 
    end; 
    MessageDlg('Test', mtInformation, [mbOK], 0); 
end; 

當組件的寬度程序在運行時或在設計時通過輸入改變我目前得到SetWidth稱爲對象檢查器的相應字段中的值。但是,當我在設計時使用鼠標調整組件大小時,對象檢查器的「寬度」字段會更新,但沒有消息框顯示,因此我的SetWidth過程未被調用。

我需要在鼠標調整組件大小時調用SetWidth,這樣我才能爲Paint程序設置一個標誌,以便知道它何時必須執行其他某些操作(除了重繪組件)。有沒有辦法做到這一點?

+0

+1因爲它帶來了3個很好的補充答案。當然它有自己的優點,如果只是爲了避免錯誤;-) – 2010-11-23 20:11:33

回答

6

雖然Mason Wheeler's answer是你的問題的答案,我想警告你。

重寫屬性可能會給出奇怪的結果,因爲您不能具有「虛擬」屬性,並且SetWidth也不是虛擬的。如果有人正在使用類的後代來設置寬度屬性,則不會調用您的代碼。因此,我建議不要以這種方式重寫屬性。

var Control: TControl; 
begin 
Control := MyLabel; 
Control.Width := 5000; // TMyLabel.SetWidth is not called!! 

此外:設置寬度屬性是不改變的控制作爲Deltics explains的寬度的唯一途徑。您應該重寫TControl.SetBounds。

var MyLabel: TMyLabel; 
begin 
MyLabel.SetBounds(0, 0, 100, 100); // TMyLabel.SetWidth nor TControl.SetWidth is called!! 

但似乎你想限制你的控制的寬度。那麼你最好覆蓋TControl.CanResize這是爲此目的而設計的。或者,如果您只是想對任何種類的調整大小作出反應,最好覆蓋TControl.Resize

+0

感謝您的建議,我應該能夠解決我與TControl.Resize的問題。 – 2010-11-23 21:26:27

4

當你重新聲明寬度,則需要同時指定閱讀它,否則您將無法修改它在Object Inspector。如果你不打算改變方式閱讀的作品,那麼只要給它一個虛函數:

procedure TMyLabel.GetWidth: Integer; 
begin 
    result := inherited Width; 
end; 
+0

謝謝,但它似乎很奇怪,我可以改變對象檢查器中的組件的寬度,而無需指定一個讀取訪問器與旁邊的寫入訪問器財產聲明。 – 2010-11-23 21:10:32

6

我現在不能檢查,但IIRC我懷疑設計師重新調整使用的setBounds你的控制()而不是設置單獨的左,頂部,寬度和高度屬性。

幸運的是,SetBounds()是虛擬的,因此您可以在自定義控件類中簡單地覆蓋它。