Delphi 2009 - установка значений свойств по умолчанию в пользовательских компонентах Delphi - PullRequest
2 голосов
/ 27 августа 2009

Это должно быть очень просто, но я не могу найти точный ответ, который хочу. У меня есть пользовательский элемент управления Delphi на основе TSpeedButton. Я хочу, чтобы свойство подписи SpeedButton всегда имело значение «Комментарии», но я не хочу устанавливать его во время выполнения, я хочу установить его в самом компоненте, чтобы при размещении его в форме он уже заполнялся текст. Я также хочу установить высоту и ширину кнопки, но я полагаю, что метод для этого будет таким же, как для установки заголовка.

Для полноты вот код компонента:

unit CustomSpeedButton;

interface

uses
  SysUtils, Classes, Controls, Buttons;

type
  TCustomSpeedButton = class(TSpeedButton)
  private
    FCommentText: string;
    FCommentTitle: string;

    procedure SetCommentText(const Value: string);
    procedure SetCommentTitle(const Value: string);

    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }

  published
    { Published declarations }
    property CommentTitle: string read FCommentTitle write SetCommentTitle;
    property CommentText: string read FCommentText write SetCommentText;
  end;

procedure Register;

implementation

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

{ TCustomSpeedButton }

procedure TCustomSpeedButton.SetCommentText(const Value: string);
begin
  FCommentText := Value;
end;

procedure TCustomSpeedButton.SetCommentTitle(const Value: string);
begin
  FCommentTitle := Value;
end;

end.

Ответы [ 3 ]

3 голосов
/ 28 августа 2009

Поскольку вы хотели, чтобы свойство Caption было выполнено правильно, ответ Мейсона не сработает, потому что он пропустил вещь csSetCaption, и его предложение о значении default не будет работать, так как и Caption, и ваши свойства строковые типы.

Ниже приведены единицы, которые вы хотите.

Поведение выглядит следующим образом:

  1. изначально значение свойства Caption будет равно «Комментарии»
  2. пользователи могут переопределить это во время разработки, установив новое значение

(Если вы не хотите 2., тогда вам нужно назначить свойство Caption в переопределенном методе Loaded, как упомянул Кен; однако из вашего вопроса не было ясно, хотите ли вы этого. Если вы этого хотите, то перефразируйте ваш вопрос.)

Вот как работает код.

Для строковых свойств нельзя указывать систему потоковой передачи любого по умолчанию . Но вы можете установить начальное значение времени разработки в конструкторе: Caption: = DefaultCustomSpeedButtonCaption;

Для свойства Caption необходимо также отключить назначение свойства Caption по умолчанию (в противном случае ваш компонент автоматически получит заголовок, например «CustomSpeedButton1»). Эта строка делает это за вас: ControlStyle: = ControlStyle - [csSetCaption];

Наконец, хорошей практикой является разделение регистрации вашего компонента на отдельную единицу. Это позволяет вам иметь пакет времени разработки, который регистрирует ваши компоненты в IDE, и пакет времени выполнения (или вообще никакого пакета) для использования ваших компонентов в ваших приложениях.

Если у вас есть значок компонента, то вы также загружаете его в блок регистрации (поскольку он необходим только во время разработки).

Рэй Конопка написал отличную книгу по написанию компонентов, которая все еще очень актуальна: Разработка пользовательских компонентов Delphi 3 Как и во многих хороших книгах по Delphi, она не печатается, но вы можете заказать копию в формате PDF на его сайте .

Я не уверен, для чего нужны ваши свойства CommentTitle и CommentText, поэтому я сохранил их в приведенном ниже источнике.

Листинг 1: фактический компонент

unit CustomSpeedButtonUnit;

interface

uses
  SysUtils, Classes, Controls, Buttons;

const
  DefaultCustomSpeedButtonCaption = 'Comments';

type
  TCustomCustomSpeedButton = class(TSpeedButton)
  strict private
    FCommentText: string;
    FCommentTitle: string;
  strict protected
    procedure SetCommentText(const Value: string); virtual;
    procedure SetCommentTitle(const Value: string); virtual;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    property CommentTitle: string read FCommentTitle write SetCommentTitle;
    property CommentText: string read FCommentText write SetCommentText;
  end;

  TCustomSpeedButton = class(TCustomCustomSpeedButton)
  published
// note you cannot use 'default' for string types; 'default' is only valid for ordinal ordinal, pointer or small set type
// [DCC Error] CustomSpeedButtonUnit.pas(29): E2146 Default values must be of ordinal, pointer or small set type
//    property Caption default DefaultCustomSpeedButtonCaption;
    property CommentTitle;
    property CommentText;
  end;

implementation

constructor TCustomCustomSpeedButton.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Caption := DefaultCustomSpeedButtonCaption;
  ControlStyle := ControlStyle - [csSetCaption];
end;

destructor TCustomCustomSpeedButton.Destroy;
begin
  inherited Destroy;
end;

procedure TCustomCustomSpeedButton.SetCommentText(const Value: string);
begin
  FCommentText := Value;
end;

procedure TCustomCustomSpeedButton.SetCommentTitle(const Value: string);
begin
  FCommentTitle := Value;
end;

end.

Листинг 2: регистрация компонента

unit CustomSpeedButtonRegistrationUnit;

interface

procedure Register;

implementation

uses
  CustomSpeedButtonUnit;

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

end.
2 голосов
/ 28 августа 2009

Вам необходимо установить исходные значения в конструкторе компонента.

РЕДАКТИРОВАТЬ: Вы также хотите добавить add ControlStyle := ControlStyle - [csSetCaption]; в конструктор.

1 голос
/ 05 сентября 2014

@ Etherman: Если вам нужно иметь строковое свойство со значением по умолчанию И вы хотите сохранить его в DFM - даже если оно пустое - вы должны сделать это самостоятельно. К счастью, Delphi предлагает вам методы для этого. Посмотрите на этот код:

type
  TMyComp = class(TControl)
  private
    FMyStringProperty: string;
    procedure WriteMyStringProperty(Writer: TWriter);
    procedure DefineProperties(Filer: TFiler);  override;
  public
    constructor Create(AOwner: TComponent); override;
  published
    property MyStringProperty: string read FMyStringProperty write FMyStringProperty stored False;
  end;


implementation


constructor TMyComp.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMyStringProperty := 'my default value';
end;

procedure TMyComp.WriteMyStringProperty(Writer: TWriter);
begin
  Writer.WriteString(FMyStringProperty);
end;

procedure TMyComp.DefineProperties(Filer: TFiler);
begin
  inherited DefineProperties(Filer);
  Filer.DefineProperty('MyStringProperty', nil, WriteMyStringProperty, True);
end;
...