我发现之前已经向VCL询问了this个问题,但我还没有运气,可以将问题的答案用于Firemonkey TMemo
。
我注意到memo.Lines.Count
似乎总是根据我添加的数量来计算行数,而不是因为它们已经格式化(备忘录确实打开了wordwrap)。在不知道这个数字的情况下,我不知道如何开始解决这个问题。
有什么想法吗?
编辑:备忘录的宽度取决于设备的方向,显然,如果宽度改变,显示的行数可能会改变。另外,我不想改变备忘录的字体。
答案 0 :(得分:4)
Procedure ResizeMemo(AMemo: TMemo);
const
Offset = 4; //The diference between ContentBounds and ContentLayout
begin
AMemo.Height := AMemo.ContentBounds.Height + Offset;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
ResizeMemo(Memo1);
end;
答案 1 :(得分:1)
以下功能应该可以满足您的需求。它不会更改备忘录中的任何内容,并会考虑字体和任何换行符和换行符。如果将备忘录高度设置为计算值,则需要为边框添加几个像素以消除滚动条。
(将fmx.text添加到XE3的uses语句,对于其他版本可能会有所不同,因为它们会随着每个版本不断更改)
function get_memo_height(amemo:tmemo):single;
var i:integer;
astring:string;
layout:ttextlayout;
begin
Layout := TTextLayoutManager.DefaultTextLayout.Create;
astring:='';
for i:=0 to amemo.lines.count-1 do astring:=astring+amemo.lines[i]+chr(10);
Layout.BeginUpdate;
Layout.Text :=astring;
Layout.WordWrap := amemo.wordwrap;
Layout.HorizontalAlign := amemo.TextAlign;
Layout.MaxSize := PointF(amemo.width-amemo.VScrollBar.width,maxint);
Layout.VerticalAlign := tTextAlign.taLeading;
Layout.Font := amemo.Font;
Layout.TopLeft := pointf(0,0);
Layout.EndUpdate;
result:=layout.textrect.bottom;
Layout.free;
end;
答案 2 :(得分:1)
这是我的新尝试:
FMX:
object Form1: TForm1
Left = 0
Top = 0
Caption = 'Form1'
ClientHeight = 305
ClientWidth = 333
FormFactor.Width = 1920
FormFactor.Height = 1080
FormFactor.Devices = [dkDesktop]
DesignerMobile = False
DesignerWidth = 0
DesignerHeight = 0
DesignerDeviceName = ''
DesignerOrientation = 0
DesignerOSVersion = ''
object Memo1: TMemo
Touch.InteractiveGestures = [igPan, igLongTap, igDoubleTap]
Anchors = [akLeft, akTop, akRight]
Height = 257.000000000000000000
Position.X = 8.000000000000000000
Position.Y = 8.000000000000000000
TabOrder = 0
Width = 312.000000000000000000
Lines.Strings = (
'Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 L' +
'ine 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 '
'Line 2 Line 2 Line 2 Line 2 Line 2 '
''
'Line 4'
'Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 L' +
'ine 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Li' +
'ne 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Lin' +
'e 5 Line 5 Line 5 Line 5 Line 5 ')
Font.Family = 'Arial'
WordWrap = True
end
object Button1: TButton
Anchors = [akLeft, akTop, akRight]
Height = 22.000000000000000000
Position.X = 8.000000000000000000
Position.Y = 272.000000000000000000
TabOrder = 1
Text = 'Show Line Count'
Width = 312.000000000000000000
OnClick = Button1Click
end
object Memo3: TMemo
Touch.InteractiveGestures = [igPan, igLongTap, igDoubleTap]
Height = 50.000000000000000000
Position.X = 176.000000000000000000
Position.Y = 184.000000000000000000
TabOrder = 2
Visible = False
Width = 100.000000000000000000
Lines.Strings = (
'1')
end
end
PAS:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Layouts,
FMX.Memo, FMX.Text, FMX.StdCtrls, FMX.TextLayout;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Memo3: TMemo;
procedure Button1Click(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
procedure TForm1.Button1Click(Sender: TObject);
var i: integer;
layout: TTextLayout;
cont, LineHeight : real;
begin
cont := 0;
layout:= TTextLayout(memo3.Lines.Objects[0]);
LineHeight := layout.TextHeight;
for i:= 0 to memo1.Lines.Count-1 do
begin
layout:= TTextLayout(memo1.Lines.Objects[i]);
if Assigned(layout) then
begin
cont := cont + (layout.TextHeight / LineHeight);
end;
end;
showmessage('Line count according to firemonkey: ' + inttostr(memo1.Lines.Count));
showmessage('Real line count: ' + VarToStr(cont));
end;
end.
希望它有所帮助。
答案 3 :(得分:0)
这当然不优雅,但您可以将插入符号移到TMemo的末尾,然后请求CaretPosition
:
function getLastMemoLineNumber(const memo: TMemo): Integer;
var
oldCaretPosition: TCaretPosition;
begin
Assert( Assigned(memo) );
oldCaretPosition := memo.CaretPosition;
try
memo.GoToTextEnd();
Result := memo.CaretPosition.Line;
finally
memo.CaretPosition := oldCaretPosition;
end;
end;