delphi 调整标签大小不会更改标签高度

wgxvkvu9  于 2022-11-29  发布在  其他
关注(0)|答案(3)|浏览(175)

如何在调整窗体大小时自动调整标签高度?所有属性都已设置。顶部对齐、自动调整大小和自动换行。
当我更改窗体大小时,标签会很好地调整标题。但是,实际标签不会调整其高度。
这会在窗体宽度增加时留下间隙,或者使标题的底部无法读取。当标签下的控件根据标签的高度向上或向下移动时,会使标题看起来很难看。
我不喜欢使用窗体的resize事件来完成这个操作,可惜没有窗体的“resize end”事件。
需要帮忙吗?谢谢。

41ik7eoe

41ik7eoe1#

如果我没记错的话,当Autosize设置为true时,标签的高度将自动设置为Caption中文本的实际高度。
您可以尝试将Autosize设置为false,看看效果如何。

iswrvxsc

iswrvxsc2#

我已经通过继承tlabel解决了这个问题。在这个例子中,自动调整大小有一个错误(自动调整大小,自动换行和alTop)
要使其重新计算大小,您需要:

AutoSize := false;
AutoSize := true;

因此您可以覆盖调整大小过程,如下所示:

procedure TResizableLabel.Resize;
begin
  AutoSize := false;
  AutoSize := true;
end;

然而,如果你在每次调整大小时都这样做,它也会缩小宽度,所以你会从alTop中丢失父对象的宽度,如果它只是左对齐,它可能是可以的,但如果你想居中或右对齐,你需要一个更好的解决方案。
这是完整的解决方案,它只在需要时调用自动调整:

TResizableLaber = class(TLabel)
  protected
    FTextHeight, FTextWidth : integer;
    function GetCaption : TCaption;
    procedure SetCaption(ACaption : TCaption);
    function GetFont : TFont;
    procedure SetFont(AFont : TFont);
  public
    procedure Resize; override;
    property Caption : TCaption read GetCaption write SetCaption;
    property Font : TFont read GetFont write SetFont;
end;

implementation 

procedure TResizableLaber.Resize;
var
  num : double;
begin
  inherited;
  if AutoSize then
    begin
      if (FTextHeight = 0) or (FTextWidth = 0) then
        begin
            //lazy evaluation, we re evaluate every time the caption or font changes
            FTextWidth := Utills.GetTextWidth(Caption, Font);
            FTextHeight := Utills.GetTextHeight(Caption,Font);
        end;

      //TODO: there is still one bug here, set alCenter and make the last word long enough so it cant always wrapped to the line before, even though there is globally enough space
      num := (  Height / FTextHeight) - (FTextWidth /Width );
      //if num is greater then 1 it means we need an extra line, if it is lower then zero it means there is an extra line
      if (num > 1) or (num < 0) then
        begin
          //just doing this all the time will cause it to really resize and will break alTop matching the whole space
          AutoSize := false;
          AutoSize := true;
        end;
    end;
end;

function TResizableLaber.GetCaption : TCaption;
begin
  Result := inherited Caption;
end;
procedure TResizableLaber.SetCaption(ACaption : TCaption);
begin
  FTextWidth := Utills.GetTextWidth(ACaption, Self.Font);
  FTextHeight := Utills.GetTextHeight(ACaption,Self.Font);
  inherited Caption := ACaption;
end;

function TResizableLaber.GetFont : TFont;
begin
  Result := inherited Font;
end;
procedure TResizableLaber.SetFont(AFont : TFont);
begin
  FTextWidth := Utills.GetTextWidth(Caption, AFont);
  FTextHeight := Utills.GetTextHeight(Caption,AFont);
  inherited Font := AFont;
end;

class function Utills.GetTextHeight(const Text:String; Font:TFont) : Integer;
var
  bitmap: TBitmap;
begin
  bitmap := TBitmap.Create;
  try
   bitmap.Canvas.Font := Font;
   Result := bitmap.Canvas.TextHeight(Text);
  finally
   bitmap.Free;
  end;
end;

class function Utills.GetTextWidth(const Text:String; Font:TFont) : Integer;
var
  bitmap: TBitmap;
begin
  bitmap := TBitmap.Create;
  try
   bitmap.Canvas.Font := Font;
   Result := bitmap.Canvas.TextWidth(Text);
  finally
   bitmap.Free;
  end;
end;
xghobddn

xghobddn3#

我花了相当长的时间来使一系列标签的文字换行和高度都正确。(谢谢ndori),使用先将Autosize设为false,然后再将其设为true这一看似毫无意义的解决方案就是解决方案!(长)系列标签,其中的标题文本在其他位置生成,可以短至一个字符,也可以短至几行文本。因此,我需要一个固定的标签宽度,活动的自动换行和所有不同的标签之间的恒定的空白。当调整表单大小的标签。宽度(任意设置为560以下)可以调整,以适应新的形式时,调整大小。我认为真正的问题是得到标签的高度正确显示。

{ AL[] = global variable: array of TLabel
{ AL[].caption (the text) is delivered elsewhere, and can be short or long (= multiline text)
{ N_ActiveLabels = global integer variable: # of active labels to publish      }

procedure PublishListOfLabels;
var
  i : integer;
begin
  AL[0].Top := 15;        // or whatever
  AL[0].Visible := true;
  AL[0].Width := 560;     // (re)set this here as otherwise the wordwrap makes 
                          // the label text a long narrow column!
  AL[0].AutoSize := false;   // THIS IS REQUIRED!
  AL[0].AutoSize := true;    // THIS IS REQUIRED!

  if N_ActiveLabels > 1 then begin
    for i := 1 to N_ActiveLabels -1 do begin
      AL[i].Visible := true;
      AL[i].Width := 560;
      AL[i].AutoSize := false;
      AL[i].AutoSize := true;
      AL[i].Top := AL[i-1].Top + AL[i-1].Height + 18;  
                 // 18 was chosen as vertical white space between any two labels
    end;
  end;
end;

我发现不需要重新绘制(或刷新)标签。我还遇到了解决方案,如:

H := AL[i].Canvas.TextHeight(AL[i].caption);

其中H应该包含AL[i]的真实的高度(在用文本填充其标题并调用PublishListOfLabels之后)。它不起作用。我提到这一点是因为在处理相同问题的其他几个地方已经提出了这种解决方案(获得正确的TLabel高度)。[我使用柏林10.1 -也许更高的版本已经解决了Autosize.false /.true异常]

相关问题