Search code examples
delphidelphi-10.4-sydneytlabel

TLabel.AutoSize not working when Label.Align = alTop


In a Delphi 10.4.2 32-bit Delphi VCL Application, I have a TLabel set on top of a TCard:

object lblColorTransparencyInfo: TLabel
  AlignWithMargins = True
  Left = 5
  Top = 37
  Width = 156
  Height = 20
  Margins.Left = 5
  Margins.Top = 5
  Margins.Right = 5
  Margins.Bottom = 5
  Align = alTop
  Caption = 
    'Pick a color in the image to make that color transparent in the ' +
    'whole image'
  Color = clInfoBk
  ParentColor = False
  Transparent = False
  WordWrap = True
  ExplicitTop = 0
end

Label.Color is set to clInfoBk, so you can visually check the Label's size.

However, despite the Label.AutoSize is set to True, the Label's HEIGHT is much higher than its text height, despite Label.AutoSize = True:

enter image description here

Is this a bug in TLabel.AutoSize?

How can I set the Label Height to its correct text-height? (Please note that the Label's width could dynamically change during run-time which would also dynamically change the text-height at run-time).


Solution

  • This is taken from the documentation for the TCustomLabel.AutoSize property:

    When AutoSize is False, the label is fixed in size. When AutoSize is True, the size of the label readjusts whenever the text changes. The size of the label is also readjusts [sic] when the Font property changes.

    When WordWrap is True, the width of the label is fixed. If AutoSize is also True, changes to the text cause the label to change in height. When AutoSize is True and WordWrap is False, the font determines the height of the label, and changes to the text cause the label to change in width.

    It only promises to change the size when the text or font is changed -- not when the label is resized due to its parent being resized. So one could argue that there is no bug here:

    Screen recording of alTop label resizing due to its caption being changed.

    Screen recording of alTop label failing to resize due to parent resizing.

    But in any case, one very quick and dirty solution is to tell the label to autosize when it is resized. Using an interposer class,

    type
      TLabel = class(Vcl.StdCtrls.TLabel)
      protected
        procedure Resize; override;
      end;
    
    implementation
    
    { TLabel }
    
    procedure TLabel.Resize;
    begin
      inherited;
      AdjustBounds;
    end;
    

    we can make it work (almost):

    alTop label autosizing when the parent is resized

    Of course, you could make your own TLabelEx control with this addition so you can use it as easily as the standard label.