Search code examples
delphitframe

How to free up dynamically created frames?


In Delphi 2010... I have a form. On the left side of the form is a Treeview. It shows a multi-level hierarchy. Assume 5 different types of data, Type A, B, C, D and E. On the right side of the form, I have a panel in which I will create a TFrame. If I click in my Treeview on a data element of type 'A', I create a TFrame on the right side of the form which shows tFrame 'A'. Basically I am showing details of the various hierarchies of my TreeView. Each of the 5 types of data uses a different type of TFrame. While I can dynamically create the TFrames, I am having difficulty in knowing WHERE and HOW to delete/free the TFrames?

Do I create a variable which shows the TYPE of the previous TFrame? What is the PROPER way to delete a TFrame? Is it with TFrame.Free? Keep in mind I may need something like Create Frame A, Free Frame A, Create Frame B, Free Frame B, Create Frame A (again), etc...

I have tried something along the lines of...

if Assigned (TFrameA), then TFrameA.free; 

While this appears to work, this causes weird behavior (it caused a button to disappear). It also means that I need to define all 5 types of TFrames as Global Variables.

Any and all thoughts appreciated.

Thanks,

GS


Solution

  • Keep a TFrame variable so you know what the currently displayed frame is. When you display a different frame, you can free/cache the current frame first.

    If you want to cache frames, then keep five separate TFrame variables, one for each page type. When you need to show a page, create it only if you have not already done so:

    private
      CurrentFrame: TFrame;
      Frames: array[0..4] of TFrame;
    

    procedure TMyForm.TreeView1Change(Sender: TObject);
    begin
      if CurrentFrame <> nil then
      begin
        CurrentFrame.Parent := nil;
        CurrentFrame := nil;
      end;
    
      if Frames[OneOfTheIndexes] = nil then
        Frames[OneOfTheIndexes] := TAppropriateFrameType.Create(Self);
    
      Frames[OneOfTheIndexes].Parent := Panel1;
      CurrentFrame := Frames[OneOfTheIndexes];
    end;
    

    If you want to recreate frames instead, then simply remove the array and Free() the current frame before displaying a new one:

    private
      CurrentFrame: TFrame;
    

    procedure TMyForm.TreeView1Change(Sender: TObject);
    begin
      if CurrentFrame <> nil then
        FreeAndNil(CurrentFrame);
    
      CurrentFrame := TAppropriateFrameType.Create(Self);
      CurrentFrame.Parent := Panel1;
    end;