Delphi 2009 - Установка значений свойств по умолчанию в пользовательских компонентах delphi
-
20-09-2019 - |
Вопрос
Это должно быть очень просто, но я не могу найти точный ответ, который мне нужен.У меня есть пользовательский элемент управления delphi, основанный на TSpeedButton.Я хочу, чтобы свойство Caption SpeedButton всегда было 'Comments', но я не хочу устанавливать его во время выполнения, я хочу установить его в самом компоненте, чтобы, когда я размещаю его в своей форме, он уже был заполнен этим текстом.Я также хочу установить высоту и ширину кнопки, но я предполагаю, что метод для этого будет таким же, как для установки заголовка.
Для полноты картины, вот код компонента:
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.
Решение
Поскольку вы хотели, чтобы свойство Caption было выполнено правильно, ответ Мейсона не сработает, потому что он пропустил 'csSetCaption' , и его предложение о 'default' также не сработает, потому что и Заголовок, и ваши свойства являются строковыми типами.
Ниже приведены единицы измерения в том виде, в каком вы их хотите.
Поведение заключается в следующем:
- изначально значением свойства Caption будет "Комментарии"
- пользователи могут переопределить это во время разработки, установив новое значение
(Если вы не хотите 2., то вам нужно назначить свойство Caption в переопределенном загруженном методе, как упоминал Кен;однако из вашего вопроса не было ясно, хотите ли вы этого.Если да, то, пожалуйста, перефразируйте свой вопрос.)
Вот как работает код.
Для строковых свойств вы не можете намекать потоковой системе на какие-либо По умолчанию.Но вы можете установить начальное значение для времени разработки в конструкторе: Подпись := DefaultCustomSpeedButtonCaption по умолчанию;
Для свойства Caption вы также должны отключить назначение свойства Caption по умолчанию (в противном случае ваш компонент автоматически получал бы заголовок типа 'CustomSpeedButton1').Эта строка делает это за вас: ControlStyle := ControlStyle - [csSetCaption] Стиль управления: [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.
Другие советы
Вам нужно установить исходные значения в конструкторе компонента.
Редактировать:Вы также захотите добавить ControlStyle := ControlStyle - [csSetCaption];
к конструктору.
@Эфирман:В случае, если вы хотите иметь строковое свойство со значением по умолчанию И хотите сохранить его в 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;