2014-02-17 69 views
3

我發現this問題已經爲VCL問過,但我沒有任何運氣獲得該問題上Firemonkey TMemo工作的答案。我可以根據它包含的文本製作TMemo大小嗎? - Firemonkey

我注意到,memo.Lines.Count似乎總是基於我添加的行數來計算行數,而不是格式化(備忘錄確實打開了wordwrap)。不知道這個數字我不確定如何開始解決這個問題。

任何想法?

編輯:備忘錄的寬度將取決於裝置的定向,很明顯,如果寬度改變顯示可以改變的行數。另外,我想不改變備忘錄的字體。

+0

如何使用具有'DT_CALC_RECT'標誌的'DrawTextEx'? –

+0

等一下,Firemonkey,那不起作用 –

回答

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

這很好。我很高興有一個簡單的解決方案。 – Sentient

+1

只是一個簡單的參考:當我試圖在FormResize事件中調整我的備忘錄時發現ContentBounds已經失效。在調整大小之前添加'Memo.RealignContent'。 – Sentient

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; 
+1

不幸的是,這有同樣的問題。我得到的結果是我添加的行數,而不是備忘錄中顯示的行數。任何由wordwrap導致的行都不計算在內。 – Sentient

+0

@ Sentient:它適用於我在XE5上。你的Delphi/FireMonkey版本是什麼?你如何插入你的文字?我通過在鍵盤上輸入並輸入了一行,導致一個或幾個換行符只計爲一行。 –

+0

我想你是在描述我所看到的問題。如果我添加一條纏繞兩遍的線,所以它實際上顯示爲3,我無法知道備忘錄實際應該有多大。我需要知道的調整備忘錄的是顯示多少行。 – Sentient

0

下面的函數應該給你你想要的東西。它不會更改備忘錄中的任何內容,並會考慮字體和任何換行符和換行。如果將備忘錄高度設置爲計算值,則需要爲邊框添加幾個像素以消除滾動條。

(添加fmx.text到使用語句XE3,因爲他們不斷變化的東西在每個版本中,可能是其他的版本不同)

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; 
+0

memo1.height:= get_memo_height(memo1)+4似乎很好地工作 –

+0

我使用XE5,似乎沒有memo.VScrollBar屬性。 – Sentient

+0

對XE4,XE5使用contentbounds解決方案,但這對XE3不起作用。實際上,每次發佈都必須在Firemonkey中重寫任何內容,因此即使有維護,我仍然使用XE3。 –

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. 

希望它有助於。

+0

這對於獲得行數非常有用。我不知道TTextLayout。 – Sentient

+0

很高興幫助,@Sentient –

相關問題