代码之家  ›  专栏  ›  技术社区  ›  Mawg says reinstate Monica

如何用子属性对属性进行编码?(ReDux)

  •  4
  • Mawg says reinstate Monica  · 技术社区  · 14 年前

    我确信我得到了一个很好的答案 my previous question 因为我以前在其他问题上有过很多来自张贴在那里的人的帮助。

    但是我显然做了一些错误的事情,因为当我复制示例代码时,对象检查器为MyProp属性向我显示的是一个单独的文本输入字段。我希望看到类似于字体属性的内容,包括间距、字体系列等,也就是说,我希望看到树结构,但我没有看到MyProp属性的颜色、高度或宽度属性。

    有什么想法吗?我又一次准确地复制了代码。


    编辑:我忘记提到(在这个问题中)我使用的是tms scripter pro,它允许用户在运行时设计表单,并提供自己的对象检查器,但我想这可能是从标准的delphi东西派生出来的。

    不管怎样,我似乎太笨了,无法编写Delphi代码,因为我无法让它正常工作。


    编辑:tms向我保证,如果具有“sub-properties”)的类是从tpresistent派生的,那么它将显示在具有子属性的对象检查器中,就像字体、锚等。

    使用此代码时,“警告”属性在对象检查器中显示为文本字段,没有子属性

    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.
    
    2 回复  |  直到 14 年前
        1
  •  4
  •   Community Artem    7 年前

    这个 original version 属于 the demo code 忽略了创建属性对象的实例。

    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
  •  2
  •   Bharat    14 年前

    this article 它清楚地解释了如何创建子属性。