title: Delphi FMX component ghosting removing subcomponents
body: <p>I have created an FMX component that is a button array. This has a simple column and row count property.
  Each of the buttons in the array is a component itself and when the row or column count is changed I delete all of the buttons and re-create the number needed.</p>
  
  <p>The problem I have is that after removing the components they continue to ghost on screen.
  For example the default column and row count is 10 but for phone format I change this at design time to 5 x 5. Here is the result...</p>
  
  <p><img src="https://i.stack.imgur.com/SCT7D.jpg" alt="Button array component proble"></p>
  
  <p>I am sure this is related to the "Stored" property however I am sure I have tried turning this on and off on the buttons and the array with no difference.
  Source code to the component (tried to remove excess code):</p>
  
  <pre><code>type
    TLFArrayButton = class(TStyledControl)
  
    TLFButtonArray = class(TPanel)
    private
      { Private declarations }
      FButtons: Array[0..9, 0..9] of TLFArrayButton;
      Sections: Array[0..3] of TRectangle;
      SectionsText: Array[0..3] of TText;
      FRowCount: integer;
      FColCount: integer;
      FFourUp: boolean;
      FOnArrayButtonClick: TLFButtonArrayButtonClick;
      procedure SetColCount(const Value: integer);
      procedure SetRowCount(const Value: integer);
      procedure CheckButtonArraySize;
      procedure PositionButtons;
      procedure FreeButtons;
      function GetButtonsText(Col, Row: Integer): String;
      procedure SetButtonsText(Col, Row: Integer; const Value: String);
      function GetButtonEnabled(Col, Row: Integer): Boolean;
      procedure SetButtonEnabled(Col, Row: Integer; const Value: Boolean);
      procedure SetFourUp(const Value: boolean);
      procedure OnButtonClick(Sender: TObject);
  
      procedure OnButtonMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Single);
      procedure SetupSectionHeadders;
      function GetButton(id: integer): TLFArrayButton;
      function GetSectionHeadding(idx: integer): string;
      procedure SetSectionHeadding(idx: integer; const Value: string);
      procedure SetOnArrayButtonClick(const Value: TLFButtonArrayButtonClick);
    protected
      { Protected declarations }
      function GetStyleObject: TFmxObject; override;
      procedure Resize; override;
      procedure ApplyTriggers; virtual;
      procedure DoButtonClick(id: integer); virtual;
    public
      { Public declarations }
      constructor Create(AOwner: TComponent); override;
      destructor Destroy; override;
      property Button[id: integer]: TLFArrayButton read GetButton;
      property ButtonEnabled[Col, Row: Integer]: Boolean read GetButtonEnabled write SetButtonEnabled;
      property ButtonsText[Col, Row: Integer]: String read GetButtonsText write SetButtonsText;
      property SectionHeadding[idx: integer]: string read GetSectionHeadding write SetSectionHeadding;
    published
      { Published declarations }
      property FourUp: boolean read FFourUp write SetFourUp stored true default false;
      property ColCount: integer read FColCount write SetColCount stored true default 10;
      property RowCount: integer read FRowCount write SetRowCount stored true default 10;
      property OnArrayButtonClick: TLFButtonArrayButtonClick read FOnArrayButtonClick write SetOnArrayButtonClick;
   end;
  
  procedure Register;
  
  implementation
  
  {$R *.res}
  
  procedure Register;
  begin
    RegisterComponents('LightFactoryFMX', [TLFButtonArray]);
    RegisterComponents('LightFactoryFMX', [TLFArrayButton]);
  end;
  
  { TLFButtonArray }
  
  procedure TLFButtonArray.CheckButtonArraySize;
  var
    r, c, i: Integer;
  begin
    FreeButtons;
    InvalidateRect(RectF(0,0,width,height));
    i := 1;
    for r := 0 to FRowCount-1 do
    begin
      for c := 0 to FColCount-1 do
      begin
        FButtons[r,c] := TLFArrayButton.Create(Self);
        FButtons[r,c].Parent := Self;
        FButtons[r,c].Stored := false;
        FButtons[r,c].Locked := true;
        FButtons[r,c].ShowID := true;
        FButtons[r,c].ID := i;
        FButtons[r,c].OnClick := OnButtonClick;
        inc(i);
      end;
    end;
  end;
  
  constructor TLFButtonArray.Create(AOwner: TComponent);
  begin
    inherited;
    Stored := false;
    StyleLookup := 'panelstyle';
    FFourUp := false;
    FColCount := 10;
    FRowCount := 10;
    CheckButtonArraySize;
    PositionButtons;
  end;
  
  procedure TLFButtonArray.FreeButtons;
  var
    r, c: Integer;
  begin
    for r := 0 to FRowCount-1 do
    begin
      for c := 0 to FColCount-1 do
      begin
        if assigned(FButtons[r, c]) then
        begin
          FButtons[r, c].Free;
          FButtons[r, c] := NIL;
        end;
      end;
    end;
  end;
  
  procedure TLFButtonArray.PositionButtons;
  var
    r, c, s, b, loc_col, loc_row, num_per_sec: Integer;
    x, y, dw, dh: single;
    tmpBtn: TLFArrayButton;
  begin
    if FFourUp then
    begin
      loc_col := ColCount div 2;
      loc_row := RowCount div 2;
      num_per_sec := loc_col * loc_row;
      //
      dw := (Width - INTER_SECTION_SPACING - ((FColCount+1) * BUTTON_SPACING)) / FColCount;
      dh := (Height - INTER_SECTION_SPACING - (Sections[0].Height * 2) - ((FRowCount+1) * BUTTON_SPACING)) / FRowCount;
      x := BUTTON_SPACING;
      y := BUTTON_SPACING;
  
      for s := 0 to 3 do
      begin
        x := Sections[s].Position.X;
        y := Sections[s].Position.Y + Sections[s].Height + BUTTON_SPACING;
        for b := 1 to num_per_sec do
        begin
          tmpBtn := GetButton((s*num_per_sec) + b);
          if assigned(tmpBtn) then
          begin
            tmpBtn.Position.X := x;
            tmpBtn.Position.Y := y;
            tmpBtn.Width := dw;
            tmpBtn.Height := dh;
            x := x + dw + BUTTON_SPACING;
            if x &gt; (Sections[s].Position.X + Sections[s].Width) then
            begin
              x := Sections[s].Position.X;
              y := y + dh + BUTTON_SPACING;
            end;
          end;
        end;
      end;
    end
    else
    begin
      dw := (Width - ((FColCount+1) * BUTTON_SPACING)) / FColCount;
      dh := (Height - ((FRowCount+1) * BUTTON_SPACING)) / FRowCount;
      x := BUTTON_SPACING;
      y := BUTTON_SPACING;
      for r := 0 to FRowCount-1 do
      begin
        for c := 0 to FColCount-1 do
        begin
          FButtons[r,c].Position.X := x;
          FButtons[r,c].Position.Y := y;
          FButtons[r,c].Width := dw;
          FButtons[r,c].Height := dh;
          x := x + dw + BUTTON_SPACING;
        end;
        x := BUTTON_SPACING;
        y := y + dh + BUTTON_SPACING;
      end;
    end;
  end;
  
  procedure TLFButtonArray.Resize;
  begin
    inherited;
    if FourUp then
      SetupSectionHeadders;
    PositionButtons;
  end;
  
  destructor TLFButtonArray.Destroy;
  begin
    FreeButtons;
    inherited;
  end;
  
  procedure TLFButtonArray.SetColCount(const Value: integer);
  begin
    if FColCount &lt;&gt; Value then
    begin
      if (Value &gt; 0) and (Value &lt; 11) then
      begin
        FColCount := Value;
        CheckButtonArraySize;
        PositionButtons;
      end;
    end;
  end;
  
  procedure TLFButtonArray.SetRowCount(const Value: integer);
  begin
    if FRowCount &lt;&gt; Value then
    begin
      if (Value &gt; 0) and (Value &lt; 11) then
      begin
        FRowCount := Value;
        CheckButtonArraySize;
        PositionButtons;
      end;
    end;
  end;
  </code></pre>