For example: I have a TFrame (called TPageFrame) that has a number of controls, e.g. TreeView aligned Left, splitter, and main clientarea consisting of an edit and RichEdit, as in image below:
Code looks something like this:
type
TPageFrame = class(TFrame)
Panel1: TPanel;
Splitter1: TSplitter;
Panel2: TPanel;
Panel3: TPanel;
Panel4: TPanel;
Edit1: TEdit;
RichEdit1: TRichEdit;
TreeView1: TTreeView;
private
{ Private declarations }
public
end;
In the Main Form I have a a RzTabControl with a few tabs. As I move to a new tab, a new Frame will be created (stored in a Frame array) and it's parent is set to the RzTabControl.
type
TForm1 = class(TForm)
RzTabControl1: TRzTabControl;
procedure RzTabControl1Change(Sender: TObject);
private
{ Private declarations }
FFrameArr: array[0..5] of TPageFrame;
public
{ Public declarations }
end;
procedure TForm1.RzTabControl1Change(Sender: TObject);
var
Index: Integer;
PageFrame: TPageFrame;
begin
Index := RzTabControl1.TabIndex;
Self.Caption := Index.ToString;
if FFrameArr[Index] = nil then
begin
PageFrame := TPageFrame.Create(Self);
PageFrame.Name := 'PageFrame' + Index.ToString;
PageFrame.Parent := RzTabControl1;
PageFrame.Align := alClient;
PageFrame.Visible := True;
FFrameArr[Index] := PageFrame;
end;
end;
Problem: While the Frame is being created and having it's parent set, there is a lot of "Display noise":
See how edit control is painted twice in 2 positions. (Would be easier to demonstrate with a video...)
How can this kind of flicker be avoided?
There are a few problems with the code by @RaelB, such as incorrect use of try/finally, not handling any exceptions that might arise to locally created variables, etc.
The correct (IMO) code should be:
if not Assigned(FFrameArr[Index]) then begin
Screen.Cursor := crHourGlass;
try
// Defer updates
SendMessage(Handle, WM_SETREDRAW, WPARAM(False), 0);
try
PageFrame := TPageFrame.Create(Self);
try
PageFrame.Name := 'PageFrame' + Index.ToString;
PageFrame.Visible := False;
PageFrame.Parent := RzTabControl1;
PageFrame.Align := alClient;
PageFrame.Visible := True;
FFrameArr[Index] := PageFrame;
except
PageFrame.Free;
raise
end;
finally
// Make sure updates are re-enabled
SendMessage(Handle, WM_SETREDRAW, WPARAM(True), 0);
end;
PageFrame.Hide;
PageFrame.Show;
RzTabControl1.Invalidate;
finally
Screen.Cursor := crDefault;
end;
end;