2010-09-28 76 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