How do I prevent a FMX TMemo from updating while loading data into it? Memo1.Lines.BeginUpdate
doesn't seems to be the answer.
Code to reproduce:
Create a new FMX application Place a TMemo on the form Add a OnDoubleClickEvent to it and then the following code:
procedure TForm2.Memo1DblClick(Sender: TObject);
var
i: Integer;
const
Line = '1234567890_1234567890_1234567890_1234567890_1234567890_1234567890';
begin
Memo1.Lines.Clear;
Memo1.ControlType := TControlType.Platform;
Memo1.Lines.BeginUpdate;
for i := 1 to 1000 do
Memo1.Lines.Add(Line);
Memo1.Lines.EndUpdate;
end;
While running the program you'll see the Memo gets updated while adding data despite the call to BeginUpdate
/ EndUpdate
CodePudding user response:
The easiest way is to not update the memo directly, but via another object, like a TStringList:
procedure TForm2.Memo1DblClick(Sender: TObject);
var
i: Integer;
sl: TStrings;
const
Line = '1234567890_1234567890_1234567890_1234567890_1234567890_1234567890';
begin
Memo1.ControlType := TControlType.Platform;
sl:=TStringList.Create;
try
for i := 1 to 1000 do
sl.Add(Line);
..either..
Memo1.Lines.Clear;
Memo1.Lines.AddStrings(sl);
..or..
Memo1.Lines.Text:=s1.Text;
finally
sl.free
end
end;
An alternative (WINDOWS ONLY) is to disable screen updates while adding:
Uses WinAPI.Windows, WinAPI.Messages, FMX.Platform.Win;
procedure TForm2.Memo1DblClick(Sender: TObject);
var
i: Integer;
const
Line = '1234567890_1234567890_1234567890_1234567890_1234567890_1234567890';
begin
Memo1.Lines.Clear;
Memo1.ControlType := TControlType.Platform;
PostMessage(FmxHandleToHWND(Handle),WM_SETREDRAW,0,0);
try
for i := 1 to 1000 do
Memo1.Lines.Add(Line);
finally
PostMessage(FmxHandleToHWND(Handle),WM_SETREDRAW,1,0);
Memo1.Invalidate // May be unnecessary //
end;
end;
This will disable all screen updates to the form while updating. I believe it will also disable the Memo1 screen updates as well. Unfortuntely, FMX objects are not Windows objects, so you cannot disable screen updates directly for the Memo itself.
You can implement the LockDrawing/UnlockDrawing on the TForm level by including this CLASS HELPER:
{$IFDEF MSWINDOWS }
Uses WinAPI.Windows, WinAPI.Messages, FMX.Platform.Win;
{$ENDIF }
TYPE
TFormHelper = CLASS HELPER FOR TForm
PROCEDURE LockDrawing;
PROCEDURE UnlockDrawing;
END;
{ TFormHelper }
PROCEDURE TFormHelper.LockDrawing;
BEGIN
{$IFDEF MSWINDOWS }
PostMessage(FmxHandleToHWND(Handle),WM_SETREDRAW,0,0);
{$ENDIF }
END;
PROCEDURE TFormHelper.UnlockDrawing;
BEGIN
{$IFDEF MSWINDOWS }
PostMessage(FmxHandleToHWND(Handle),WM_SETREDRAW,1,0);
RedrawWindow(FmxHandleToHWND(Handle),NIL,0,RDW_ERASE OR RDW_FRAME OR RDW_INVALIDATE OR RDW_ALLCHILDREN)
{$ENDIF }
END;
That would make your event handler look like this:
procedure TForm2.Memo1DblClick(Sender: TObject);
var
i: Integer;
const
Line = '1234567890_1234567890_1234567890_1234567890_1234567890_1234567890';
begin
Memo1.Lines.Clear;
Memo1.ControlType := TControlType.Platform;
LockDrawing;
try
for i := 1 to 1000 do
Memo1.Lines.Add(Line);
finally
UnlockDrawing
end;
end;
CodePudding user response:
The FMX TControl
class has BeginUpdate()
/ EndUpdate()
methods, so just try this:
procedure TForm2.Memo1DblClick(Sender: TObject);
var
i: Integer;
const
Line = '1234567890_1234567890_1234567890_1234567890_1234567890_1234567890';
begin
Memo1.Lines.Clear;
Memo1.BeginUpdate;
for i := 1 to 1000 do
Memo1.Lines.Add(Line);
Memo1.EndUpdate;
end;