You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Delphi的VCL TControlList中设置单个行的可变高度?

TControlList 实现可变行高的正确方案

问题根源

TControlList的ItemHeight是全局属性,作用是统一设置所有行的高度。在OnBeforeDrawItem事件中修改该属性会导致控件布局混乱——因为这个事件属于绘制阶段,此时控件已经完成了行布局计算,修改全局行高会让后续行的位置偏移,最终视图错乱。

正确实现方式

使用OnMeasureItem事件指定单行高度,这个事件在控件计算行布局前触发,能单独为每行设置高度且不会影响全局布局。

步骤1:绑定OnMeasureItem事件

在Delphi设计器中,为TControlList控件添加OnMeasureItem事件处理函数,代码如下:

procedure TForm9.ControlList1MeasureItem(AIndex: Integer; var AHeight: Integer);
begin
  // 根据行索引设置对应高度
  if AIndex = 3 then
    AHeight := 30
  else
    AHeight := 70;
end;

步骤2:优化OnBeforeDrawItem绘制逻辑

无需在OnBeforeDrawItem中修改ItemHeight,直接利用事件传入的ARect参数(该参数已根据OnMeasureItem设置的高度计算出当前行的绘制区域)完成内容绘制即可:

procedure TForm9.ControlList1BeforeDrawItem(AIndex: Integer; ACanvas: TCanvas; ARect: TRect; AState: TOwnerDrawState);
begin
  // 绘制背景
  ACanvas.Brush.Color := IfThen(odSelected in AState, clHighlight, clWindow);
  ACanvas.FillRect(ARect);

  // 绘制行文本(垂直居中)
  ACanvas.Font.Color := clWindowText;
  DrawText(ACanvas.Handle, PChar('第' + IntToStr(AIndex + 1) + '行'), -1, ARect, DT_CENTER or DT_VCENTER or DT_SINGLELINE);
end;

关键说明

  • OnMeasureItem是TControlList专门用于自定义行高的事件,通过修改AHeight参数为每行指定独立高度,控件会基于这些值完成正确的布局计算。
  • 务必避免在绘制阶段(如OnBeforeDrawItem)修改全局的ItemHeight属性,这会打乱控件已完成的布局,导致视图错乱。

内容的提问来源于stack exchange,提问作者DarGra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 15:44:53