如何自动调整TStringGrid行的大小

3
如何自动调整TStringGrid行(DefaultRowHeight)的大小以匹配使用的字体的高度?
我可以像这样做:
Grid.DefaultRowHeight:= Grid.Canvas.TextHeight('X')+ 4;
但它不起作用。对于小字体,行高太大了。
更新:
实际上这似乎是程序逻辑的问题。如果我多次更改字体,那么当前行高将与前一个字体更改事件中的字体大小匹配(它落后一步)。
我使用此代码拦截字体大小更改:
procedure TStrGrid.CMFontChanged(var Message: TMessage);
begin
  inherited; // let TControl react first
  DefaultRowHeight:= Canvas.TextHeight('ApApM')+ 4;
end;

它好像会执行以下步骤:

begin
  DefaultRowHeight:= Canvas.TextHeight('ApApM')+ 4;
  inherited; 
end;

(就像首先更改高度,然后实际设置正确的字体大小 - 因此高度落后一步)

2个回答

5

与此订单无关:继承的CMFontChanged消息处理程序和DefaultRowHeight属性设置器都会调用invalidate。这是由于当前字体设置尚未更新造成的:

procedure TStrGrid.CMFontchanged(var Message: TMessage);
begin
  Canvas.Font := Font;
  DefaultRowHeight := Canvas.TextHeight('Ap') + GridLineWidth + 3;
end;

说明:

仅使 flags 窗口无效,以便在将来的某个时间重新绘制窗口(网格)。这肯定会在获取文本高度之后发生。作为替代方案,您可以在请求新文本高度之前调用 Repaint,但这将导致双重重绘,因此需要设置 Canvas.Font


2

当涉及到事件排序相关问题时,最简单和最快的解决方案通常是通过PostMessage(从您的CMFontChanged处理程序)向自己发送消息,并在接收到发布的消息时进行更新。

这样做的好处是它不会干扰网格需要执行的任何更新内部状态的操作。


感谢您的解决方案。尽管它是最好的(也是正确的),但我使用了NGLN的技巧,因为它只需要一行代码 :) 即使NGLN的技巧需要额外的绘制,也没关系,因为字体很少更改(如果有的话)。 - Gabriel
@Altar 我肯定不会把我的答案描述为“hack”,它也不需要额外的涂漆。 - NGLN
@Heinrich,您的建议确实解决了许多这些问题。但是我刚刚测试了一下,它对于这种情况不起作用。遗憾。 - NGLN
@NGLN 我总是担心在“thing change handler”中更改“thing”时会产生副作用。但在这种情况下,这似乎是一个快速有效的解决方案。那就试试吧 :) - Heinrich Ulbricht
好的,我在这里改变的不是“东西”。我只是将“更改后的东西”分配给Canvas.Font。设置Canvas.Font不会触发CMFontChanged - NGLN

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接