Search code examples
delphipropertiescaptiondelphi-10.2-tokyo

MyLabel's Caption of TCustomLabel is not changing


I have created a component TMyLabel which inherits from TCustomLabel.

I want to add periods at the end of the Caption if a Boolean property SetPeriodAtEnd is set to True, and remove periods if it is set to False.

I have declared the Boolean property:

property SetPeriodAtEnd: Boolean read fPeriodAtEnd write SetPeriodAtEnd;
procedure TMyLabel.SetPeriodAtEnd(Value: Boolean);
begin
  fPeriodAtEnd := Value;
  if fPeriodAtEnd then
    Caption := Caption + '.......';
end;

This works when SetPeriodAtEnd() is changed only once. Later ...... gets added even for a False value.

Also, my motive was to add periods ...... only in Caption for viewing and not as value. For example, Caption := hello.... for viewing and store Caption as hello without periods. Is this possible?

Can select different font style and color for only cDots?


Solution

  • For what you are attempting to do, you can override the virtual GetLabelText() method:

    Returns the value of the Caption property.

    Call GetLabelText to obtain the string that appears as the text of the label.

    Internally, TCustomLabel uses GetTextLabel() when drawing its Caption, and when resizing itself when the Caption changes and AutoSize is true. So, you can override GetLabelText() to provide a different string than what the Caption is set to, eg:

    type
      TMyLabel = class(TCustomLabel)
      private
        fPeriodAtEnd: Boolean;
        procedure SetPeriodAtEnd(Value: Boolean);
      protected
        function GetLabelText: string; override;
      published
        property SetPeriodAtEnd: Boolean read fPeriodAtEnd write SetPeriodAtEnd;
      end;
    
    ...
    
    uses
      System.StrUtils;
    
    function TMyLabel.GetLabelText: string;
    const
      cDots = '.......';
    begin
      Result := inherited GetLabelText;
      if fPeriodAtEnd then
      begin
        if not EndsText(cDots, Result) then
          Result := Result + cDots;
      end
      else begin
        if EndsText(cDots, Result) then
          Result := LeftStr(Result, Length(Result)-Length(cDots));
      end;
    end;
    
    procedure TMyLabel.SetPeriodAtEnd(Value: Boolean);
    begin
      if fPeriodAtEnd <> Value then
      begin
        fPeriodAtEnd := Value;
        Perform(CM_TEXTCHANGED, 0, 0); // triggers Invalidate() and AdjustBounds()
      end;
    end;