Pergunta

Isso deve ser muito simples, mas não consigo encontrar a resposta exata que quero. Eu tenho um controle Delphi personalizado baseado no Button TspeedButton. Eu quero que a propriedade Legenda do Speedbutton seja sempre 'Comentários', mas não quero defini-lo em tempo de execução, quero defini-lo no próprio componente, para que, quando o coloque na minha forma, já esteja preenchido com isso texto. Também quero definir a altura e a largura do botão, mas imagino que o método para fazer isso seja o mesmo que definir a legenda.

Por uma questão de completude, aqui está o código do componente:

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.
Foi útil?

Solução

Como você queria que a propriedade da legenda fosse feita corretamente, a resposta de Mason não funcionará porque ele perdeu a coisa de 'cssetcaption', e sua sugestão sobre 'padrão' também não funcionará porque a legenda e suas propriedades são tipos de string.

Abaixo estão as unidades como você deseja.

O comportamento é o seguinte:

  1. Intialmente, o valor da propriedade da legenda será 'comentários'
  2. Os usuários podem substituir isso no tempo de design definindo um novo valor

(Se você não deseja 2., precisará atribuir a propriedade de legenda em um método carregado com excesso como Ken mencionado; no entanto, não ficou claro em sua pergunta se você quiser. Se você quiser, reformular sua pergunta. )

É assim que o código funciona.

Para propriedades de string, você não pode sugerir o sistema de streaming de qualquer predefinição. Mas você pode definir um valor inicial para o tempo de design no construtor: Legenda: = DefaultCustomSpeedButtonCaption;

Para a propriedade Legenda, você também deve desativar a atribuição padrão da propriedade Legenda (caso contrário, seu componente seria automaticamente uma legenda como 'CustomSpeedButton1'). Esta linha faz isso por você: ControlStyle: = ControlStyle - [cSsetCaption];

Finalmente, é uma boa prática dividir seu registro de componentes em uma unidade separada. Isso permite que você tenha um pacote de tempo de design que registre seus componentes no IDE e um pacote de tempo de execução (ou nenhum pacote) para usar seus componentes em seus aplicativos.

Se você possui um ícone de componente, também o carrega na unidade de registro (pois é necessário apenas no tempo de design).

Ray Konopka escreveu um excelente livro sobre redação de componentes, que ainda é muito válida: Desenvolvendo componentes personalizados Delphi 3Como muitos bons livros de Delphi, está esgotado, mas você pode Encomende uma cópia em PDF em seu site.

Não sei ao certo para que são as suas propriedades de comentários e comentários, então eu os mantive na fonte abaixo.

Listagem 1: Componente real

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.

Listagem 2: Registro de componentes

unit CustomSpeedButtonRegistrationUnit;

interface

procedure Register;

implementation

uses
  CustomSpeedButtonUnit;

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

end.

Outras dicas

Você precisa definir os valores originais no construtor do componente.

Editar: você também vai querer colocar add ControlStyle := ControlStyle - [csSetCaption]; para o construtor.

@Etherman: Caso você queira ter uma propriedade de string com valor padrão e deseja salvá -lo no DFM - mesmo que esteja em branco - você precisa fazer isso sozinho. Felizmente, Delphi fornece métodos para fazer isso. Dê uma olhada neste código:

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;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top