如何防止FMX TMemo在加载数据时进行更新?Memo1.Lines.BeginUpdate似乎不是解决方案。
要重现的代码:
创建一个新的FMX应用程序,在表单上放置一个TMemo,向其中添加一个OnDoubleClickEvent,然后执行以下代码:
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;在运行该程序时,您将看到尽管调用了BeginUpdate / EndUpdate,但在添加数据时备忘录仍会更新
发布于 2021-10-04 05:51:08
最简单的方法是不直接更新备忘录,而是通过另一个对象,如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;另一种方法(仅限WINDOWS)是在添加以下内容时禁用屏幕更新:
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;这将在更新时禁用表单的所有屏幕更新。我相信它也会禁用Memo1的屏幕更新。不幸的是,FMX对象不是Windows对象,因此您不能直接禁用备忘录本身的屏幕更新。
你可以通过包含这个类的帮助器在TForm级别上实现LockDrawing/UnlockDrawing:
{$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;这将使您的事件处理程序看起来像这样:
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;https://stackoverflow.com/questions/69431341
复制相似问题