2010-09-28 75 views
4

我相信我對my previous question得到了很好的回答,因爲我之前對發佈在那裏的人的其他問題有很多幫助。如何使用子屬性編碼屬性? (REDX)

但我明顯做錯了什麼,因爲當我複製示例代碼時,對象檢查器爲MyProp屬性顯示的是單個文本輸入字段。我期待看到類似Font屬性的東西,包括Pitch,字體系列等等,也就是我期望看到一個樹結構,但是我沒有看到MyProp屬性的Color,Height或Width屬性。

任何想法?再次,我精確地複製了該代碼。


編輯:我忘了提(在這個問題),我使用TMS編劇PRO,它允許用戶設計在運行時的形式,並提供了自己的對象檢查,但是這可能是從標準的Delphi衍生東西,我猜。

無論如何,看起來我太笨了,無法編寫Delphi,因爲我根本無法獲得這個工作。


編輯:TMS向我保證,如果用「子屬性類)從TPresistent下降那麼它會出現在子屬性,就像字體,錨定對象檢查等

當我使用此代碼,則「警告」屬性出現在Object Inspector的文本字段,並沒有子屬性

unit IntegerEditBox; 
    // An edit box which only accepts integer values and warns if the value is not in a certain range 

interface 

uses 
    SysUtils, Classes, Controls, StdCtrls, 
    EditBox_BaseClass; 

type 

    TWarning = Class(TPersistent) 
    private 
     FWarningBelowValue : Integer; 
     FWarningAboveValue : Integer; 
     FWarningEmailTo : String; 
     FWarningSmsTo : String; 
    published 
     property WarningBelowValue : Integer read FWarningBelowValue write FWarningBelowValue; 
     property WarningAboveValue : Integer read FWarningAboveValue write FWarningAboveValue; 
     property WarningEmailTo  : String read FWarningEmailTo  write FWarningEmailTo; 
     property WarningSmsTo  : string read FWarningSmsTo  write FWarningSmsTo; 
    end; 


    TIntegerEditBox = class(TEditBox_BaseClass) 
    private 
     FWarning : TWarning; 
     procedure WriteValue(const newValue : Integer); 


    protected 
     // The new property which w/e introduce in this class 
     FValue : Integer; 

    public { Public declarations } 
     Constructor Create(AOwner: TComponent); override; // This constructor uses defaults 
     property Text; 

    published { Published declarations - available in the Object Inspector at design-time } 
     property Hint; 

     // Now our own properties, which we are adding in this class 
     property Value : Integer read FValue write WriteValue; 
     property Warning : TWarning read FWarning write FWarning ; 
    end; // of class TIntegerEditBox() 

procedure Register; 

implementation 

uses 
    Dialogs; 

    procedure Register; 
    begin 
    RegisterComponents('Standard', [TIntegerEditBox]); 
    end; 

    Constructor TIntegerEditBox.Create(AOwner: TComponent); 
    begin 
    inherited; // Call the parent Create method 
    Hint := 'Only accepts a number|Only accepts a number'; // Tooltip | status bar text 
    Mandatory := True; 
    Value := 0; 
    Text := IntToStr(Value); 
    end; 

    procedure TIntegerEditBox.WriteValue(const newValue : Integer); 
    begin 
    Text := IntToStr(newValue); 
    end; 

end. 
+1

您接受的答案中的代碼至少有一個問題 - 請參閱Remy Lebeau對接受答案的評論以獲取詳細信息。 – 2010-09-28 08:05:01

+0

+1謝謝。是的,我會實現這一點 - 但我沒有看到它應該防止物體出現在對象檢查器中。 – Mawg 2010-09-28 08:27:42

+1

其他討論中的「接受答案」代碼只顯示聲明,它沒有顯示任何實際的實現代碼,所以很可能您錯過了重要步驟。我編輯了較早的代碼以顯示現在的實現。 – 2010-09-28 22:41:42

回答

4

the demo codeoriginal version忽略創建屬性對象的實例。

constructor TMyControl.Create(AOwner: TComponent) 
begin 
    inherited; 
    FMyProp := TCustomType.Create; 
end; 

不要忘記釋放它在析構函數中。

雷米對該答案的評論指出,該屬性需要以不同的方式分配。酒店的write訪問者不應直接寫入該字段。相反,它應該有一個是這樣的setter方法:

procedure TMyControl.SetMyProp(const Value: TCustomType); 
begin 
    FMyProp.Assign(Value); 
end; 

這也凸顯了該屬性類的Assign方法實現的要求,否則像「無法分配TCustomType你會得到奇怪的錯誤信息一個TCustomType「。一個簡單的實現可能是這樣的:

procedure TCustomType.Assign(Source: TPersistent); 
begin 
    if Source is TCustomType then begin 
    Color := TCustomType(Source).Color; 
    Height := TCustomType(Source).Height; 
    Width := TCustomType(Source).Width; 
    end else 
    inherited; 
end; 
+2

這些細節已被添加到其他討論中的代碼現在。 – 2010-09-28 22:45:13

2

this article 它清楚地解釋了有關創建子屬性。

+1

這似乎是對上一個問題的回答,而不是這個問題,它詢問了以前的代碼有什麼問題。 – 2010-09-28 12:58:23

+0

仍然是一個很好的答案,雖然:-) – Mawg 2010-09-29 07:45:47