When you edit a TLabel's caption in the form designer, it resizes the TLabel for you. Is there any way I can get a TMemo to do that, at runtime?
在表单设计器中编辑TLabel的标题时,它会为您调整TLabel的大小。有没有办法在运行时让TMemo做到这一点?
I'd like to be able to take a TMemo, assign something to its .lines.text property, and then tell it to resize itself and not exceed a certain width, though it can get as tall as it wants to. Anyone know how to do that?
我希望能够获取TMemo,为其.lines.text属性分配一些内容,然后告诉它调整自身大小并且不超过一定宽度,尽管它可以达到它想要的高度。谁知道怎么做?
5 个解决方案
#1
Set the WordWrap
property of the TMemo
to true, dump your text into it, count the lines, and set the height to the product of the line count and the line height, but you need to know the line height.
将TMemo的WordWrap属性设置为true,将文本转储到其中,计算行数,并将高度设置为行数和行高的乘积,但您需要知道行高。
The TMemo
does not expose a line height property, but if you're not changing the font or font size at runtime, you can determine the line height experimentally at design time.
TMemo不公开行高属性,但如果您不在运行时更改字体或字体大小,则可以在设计时通过实验确定行高。
Here's the code I used to set the height of the TMemo
that had a line height of 13 pixels. I also found that I needed a small constant to account for the TMemo
's top and bottom borders. I limited the height to 30 lines (396 pixels) to keep it on the form.
这是我用来设置行高为13像素的TMemo高度的代码。我还发现我需要一个小常数来说明TMemo的顶部和底部边界。我将高度限制为30行(396像素)以保持在表格上。
// Memo.WordWrap = True (at design time)
Memo.Text := <ANY AMOUNT OF TEXT>;
Memo.Height := Min(19 + Memo.Lines.Count * 13, 396);
If you absolutely must extract the line height from the object at runtime, then you might use Someone's answer. Or, you can use TRichEdit
, which has the SelAttributes
property containing a Height
property giving the line height.
如果绝对必须在运行时从对象中提取行高,那么您可以使用Someone的答案。或者,您可以使用TRichEdit,它具有包含Height属性的SelAttributes属性,给出行高。
-Al.
#2
This works just fine for me. The constant added (8) might vary on whether you are using a border and/or bevel, experiment with it.
这对我来说很好。添加的常数(8)可能会因您使用边框和/或斜角而有所不同,请尝试使用它。
procedure TForm1.Memo1Change(Sender: TObject);
var
LineHeight: Integer;
DC: HDC;
SaveFont : HFont;
Metrics : TTextMetric;
Increase: Integer;
LC: Integer;
begin
DC := GetDC(Memo1.Handle);
SaveFont := SelectObject(DC, Memo1.Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(Memo1.Handle, DC);
LineHeight := Metrics.tmHeight;
Increase := Memo1.Height;
LC := Memo1.Lines.Count;
if LC < 1 then
LC := 1;
Memo1.Height := LC * LineHeight + 8;
Increase := Memo1.Height - Increase;
Memo1.Parent.Height := Memo1.Parent.Height + Increase;
end;
#3
I've implemented a self-growing TMemo as a nice example of LiveBindings (one of the few useful examples I could come up with for LiveBindings in VCL).
我已经实现了一个自我增长的TMemo作为LiveBindings的一个很好的例子(我可以在VCL中为LiveBindings提供的几个有用的例子之一)。
A quote From my Delphi XE2 Development Essentials courseware manual:
引自我的Delphi XE2开发基础课程手册:
"To build this example, place a TMemo component on a VCL form, open the LiveBindings property, and select the “New LiveBinding” option. Pick the TBindExpression choice. Open BindExpressionMemo11 in the Object Inspector and set SourceComponent to Memo1 and SourceExpression to Lines.Count * 22. To get a better result at runtime, set SourceExpression to the more exact expression
“要构建此示例,请将TMemo组件放在VCL表单上,打开LiveBindings属性,然后选择”New LiveBinding“选项。选择TBindExpression选项。在Object Inspector中打开BindExpressionMemo11并将SourceComponent设置为Memo1,将SourceExpression设置为Lines。计数* 22.要在运行时获得更好的结果,请将SourceExpression设置为更精确的表达式
Font.Size - 4 + (Lines.Count + 1) * -1 * (Font.Height - 3)
Font.Size - 4 +(Lines.Count + 1)* -1 *(Font.Height - 3)
Finally, in the OnChange event handler of the TMemo, write one line of code:
最后,在TMemo的OnChange事件处理程序中,编写一行代码:
BindingsList1.Notify(Sender, '');
That’s it. Compile and run to see the growing memo in action.
而已。编译并运行以查看正在增长的备忘录。
[screenshot]
Initially, the TMemo control will be two lines high (the line with the contents, and a next line), and whenever we hit enter or word wrapping advances us to the next line, the TMemo control will grow in height (growing down actually, so make sure to leave enough space on the form for the TMemo to expand itself)."
最初,TMemo控件将是两行高(包含内容的行和下一行),每当我们按下enter或自动换行将我们推进到下一行时,TMemo控件的高度会增加(实际上,因此,请确保在表单上留出足够的空间,以便TMemo自行扩展。“
Groetjes, Bob Swart
Groetjes,Bob Swart
#4
procedure TTmpMessage.edMsgChange (Sender: TObject);
var
LineHeight : Integer;
DC : HDC;
SaveFont : HFont;
Metrics : TTextMetric;
begin
DC := GetDC ( TRxRichEdit (Sender).Handle );
SaveFont := SelectObject ( DC, TRxRichEdit (Sender).Font.Handle );
GetTextMetrics (DC, Metrics);
SelectObject (DC, SaveFont);
ReleaseDC ( TRxRichEdit (Sender).Handle, DC );
LineHeight := Metrics.tmHeight;
Height := TRxRichEdit (Sender).Lines.Count * LineHeight + 32;
end;
#5
And why not just:
为什么不呢:
Memo1.Height := Memo1.ContentBounds.Height + 5;
#1
Set the WordWrap
property of the TMemo
to true, dump your text into it, count the lines, and set the height to the product of the line count and the line height, but you need to know the line height.
将TMemo的WordWrap属性设置为true,将文本转储到其中,计算行数,并将高度设置为行数和行高的乘积,但您需要知道行高。
The TMemo
does not expose a line height property, but if you're not changing the font or font size at runtime, you can determine the line height experimentally at design time.
TMemo不公开行高属性,但如果您不在运行时更改字体或字体大小,则可以在设计时通过实验确定行高。
Here's the code I used to set the height of the TMemo
that had a line height of 13 pixels. I also found that I needed a small constant to account for the TMemo
's top and bottom borders. I limited the height to 30 lines (396 pixels) to keep it on the form.
这是我用来设置行高为13像素的TMemo高度的代码。我还发现我需要一个小常数来说明TMemo的顶部和底部边界。我将高度限制为30行(396像素)以保持在表格上。
// Memo.WordWrap = True (at design time)
Memo.Text := <ANY AMOUNT OF TEXT>;
Memo.Height := Min(19 + Memo.Lines.Count * 13, 396);
If you absolutely must extract the line height from the object at runtime, then you might use Someone's answer. Or, you can use TRichEdit
, which has the SelAttributes
property containing a Height
property giving the line height.
如果绝对必须在运行时从对象中提取行高,那么您可以使用Someone的答案。或者,您可以使用TRichEdit,它具有包含Height属性的SelAttributes属性,给出行高。
-Al.
#2
This works just fine for me. The constant added (8) might vary on whether you are using a border and/or bevel, experiment with it.
这对我来说很好。添加的常数(8)可能会因您使用边框和/或斜角而有所不同,请尝试使用它。
procedure TForm1.Memo1Change(Sender: TObject);
var
LineHeight: Integer;
DC: HDC;
SaveFont : HFont;
Metrics : TTextMetric;
Increase: Integer;
LC: Integer;
begin
DC := GetDC(Memo1.Handle);
SaveFont := SelectObject(DC, Memo1.Font.Handle);
GetTextMetrics(DC, Metrics);
SelectObject(DC, SaveFont);
ReleaseDC(Memo1.Handle, DC);
LineHeight := Metrics.tmHeight;
Increase := Memo1.Height;
LC := Memo1.Lines.Count;
if LC < 1 then
LC := 1;
Memo1.Height := LC * LineHeight + 8;
Increase := Memo1.Height - Increase;
Memo1.Parent.Height := Memo1.Parent.Height + Increase;
end;
#3
I've implemented a self-growing TMemo as a nice example of LiveBindings (one of the few useful examples I could come up with for LiveBindings in VCL).
我已经实现了一个自我增长的TMemo作为LiveBindings的一个很好的例子(我可以在VCL中为LiveBindings提供的几个有用的例子之一)。
A quote From my Delphi XE2 Development Essentials courseware manual:
引自我的Delphi XE2开发基础课程手册:
"To build this example, place a TMemo component on a VCL form, open the LiveBindings property, and select the “New LiveBinding” option. Pick the TBindExpression choice. Open BindExpressionMemo11 in the Object Inspector and set SourceComponent to Memo1 and SourceExpression to Lines.Count * 22. To get a better result at runtime, set SourceExpression to the more exact expression
“要构建此示例,请将TMemo组件放在VCL表单上,打开LiveBindings属性,然后选择”New LiveBinding“选项。选择TBindExpression选项。在Object Inspector中打开BindExpressionMemo11并将SourceComponent设置为Memo1,将SourceExpression设置为Lines。计数* 22.要在运行时获得更好的结果,请将SourceExpression设置为更精确的表达式
Font.Size - 4 + (Lines.Count + 1) * -1 * (Font.Height - 3)
Font.Size - 4 +(Lines.Count + 1)* -1 *(Font.Height - 3)
Finally, in the OnChange event handler of the TMemo, write one line of code:
最后,在TMemo的OnChange事件处理程序中,编写一行代码:
BindingsList1.Notify(Sender, '');
That’s it. Compile and run to see the growing memo in action.
而已。编译并运行以查看正在增长的备忘录。
[screenshot]
Initially, the TMemo control will be two lines high (the line with the contents, and a next line), and whenever we hit enter or word wrapping advances us to the next line, the TMemo control will grow in height (growing down actually, so make sure to leave enough space on the form for the TMemo to expand itself)."
最初,TMemo控件将是两行高(包含内容的行和下一行),每当我们按下enter或自动换行将我们推进到下一行时,TMemo控件的高度会增加(实际上,因此,请确保在表单上留出足够的空间,以便TMemo自行扩展。“
Groetjes, Bob Swart
Groetjes,Bob Swart
#4
procedure TTmpMessage.edMsgChange (Sender: TObject);
var
LineHeight : Integer;
DC : HDC;
SaveFont : HFont;
Metrics : TTextMetric;
begin
DC := GetDC ( TRxRichEdit (Sender).Handle );
SaveFont := SelectObject ( DC, TRxRichEdit (Sender).Font.Handle );
GetTextMetrics (DC, Metrics);
SelectObject (DC, SaveFont);
ReleaseDC ( TRxRichEdit (Sender).Handle, DC );
LineHeight := Metrics.tmHeight;
Height := TRxRichEdit (Sender).Lines.Count * LineHeight + 32;
end;
#5
And why not just:
为什么不呢:
Memo1.Height := Memo1.ContentBounds.Height + 5;