2016-06-02 11 views
3

Ich verwende TGridPanel, um eine Reihe von Panels zu verwalten. Ich erstelle die Platten und fügen sie dem Gridpanel Code wie folgt aus:Entfernen von Steuerelementen aus einem TGridPanel

var 
    pnl: TPanel; 
begin 
    pnl := TPanel.Create(GridPanel2); 
    pnl.Caption := 'Panel One'; 
    pnl.Tag := 1; 
    pnl.Parent := GridPanel2; 
    pnl.Name := 'pnlOne'; 

    GridPanel2.ControlCollection.AddControl(pnl); 


    pnl := TPanel.Create(GridPanel2); 
    pnl.Caption := 'Panel Two'; 
    pnl.Tag := 2; 
    pnl.Parent := GridPanel2; 
    pnl.Name := 'pnlTwo'; 

    GridPanel2.ControlCollection.AddControl(pnl); 


    pnl := TPanel.Create(GridPanel2); 
    pnl.Caption := 'Panel Three'; 
    pnl.Tag := 3; 
    pnl.Parent := GridPanel2; 
    pnl.Name := 'pnlThree'; 

    GridPanel2.ControlCollection.AddControl(pnl); 
end; 

Sie werden feststellen, dass jede Platte einen anderen Tag-Wert hat.

Ich möchte ein Panel aus dem GridPanel basierend auf dem Wert in der Tag-Eigenschaft des Panels entfernen. Ich habe den folgenden Code ausprobiert:

var 
    ii: integer ; 
    pnl: TPanel; 
begin 
    for ii := 0 to GridPanel2.ControlCollection.Count -1 do begin 
    if GridPanel2.ControlCollection[ii].Control.Tag = 1 then begin 
     pnl := GridPanel2.ControlCollection[ii].Control as TPanel; 

     GridPanel2.ControlCollection.RemoveControl(pnl); 

     freeandnil(pnl); 
    end; 
    end; 
    gridpanel2.Refresh(); 
end; 

Dies funktioniert gut, vorausgesetzt, das Panel ist das letzte Panel in der Sammlung. Wenn ich versuche, das Panel mit Tag = 1 oder Tag = 2 zu entfernen, erhalte ich einen Fehler außerhalb des Bereichs. Wenn Sie im Debugger auf "Fortfahren" klicken, wird ein Bereich angezeigt, in dem sich das entfernte Panel befand. Das Panel wird also entfernt.

Was ich gerne sehen würde ist, sagen wir, Panel 2 entfernt und nachfolgende Panels schlurften einen Platz nach unten, um keine Lücken zu lassen.

Wie mache ich das?

Ich benutze Delphi 10.1 Berlin, wenn das wichtig ist.

+1

umkehren Ihre Schleife zu bekommen, 'GridPanel2.ControlCollection.Count -1 downto 0' –

+0

Danke, @DalijaPrasnikar. Ich hatte eine Pause aus der Schleife verpasst. Da jeder Tag-Wert eindeutig ist, wird nur ein Panel gelöscht. Das behebt den Fehler außerhalb des Bereichs, aber nicht das Mischen der verbleibenden Bereiche. Nochmals vielen Dank, –

+0

Ich rollte Ihre Bearbeitung zurück, weil Sie damit den gesamten Grund für die Frage entfernt haben. Mit der hinzugefügten "Pause" tritt das von Ihnen beschriebene Problem nicht auf und daher hat die Frage für zukünftige Leser keinen Wert. Es ist unangemessen, den Code zu bearbeiten und den gesamten Grund für die Veröffentlichung zu entfernen, insbesondere nachdem jemand aufgrund dieses Fehlers in der Nachricht geantwortet hat. Sie verschwenden nicht nur die Zeit dieser Person, sondern Sie negieren die Antwort vollständig, was dazu führen kann, dass diese Person aufgrund von Stimmen aufgrund der nun falschen Antwort an Ansehen verliert. –

Antwort

2

Wie immer beim Löschen eines Elements aus einer Liste oder Sammlung müssen Sie vorsichtig vorgehen, wenn sich die Anzahl ändert. Zu Beginn der Schleife wird eine Anzahl von For-Schleifen bestimmt. Wenn Sie jetzt ein Element aus der Liste löschen, werden Sie einen nicht vorhandenen Index treffen, wenn die for-Schleife bis zum Ende fortgesetzt wird.

Sie können dies auf viele Arten vermeiden, z. indem Sie aus der Schleife ausbrechen, sobald Sie den Artikel gefunden und gelöscht haben.

freeandnil(pnl); 
    break; 

Ein anderer Weg ist die for-Schleife rückwärts

for ii := GridPanel2.ControlCollection.Count -1 downto 0 do begin 

Oder Sie Repeat Until oder While Loops verwenden, die den Zustand bei jeder Umdrehung der Schleife weiterhin überprüft können ausgeführt werden.

die Gitterplatte zu aktualisieren, nachdem Elemente rufen eine oder beide

gridpanel2.UpdateControlsRow(); 
    gridPanel2.UpdateControlsColumn(); 

jedoch löschen, fühlt es sich ziemlich schwierig den Auftrag direkt

+0

Danke, es war das Fehlen einer Pause, die den Fehler außerhalb der Grenzen verursachte. Ich kann nicht glauben, dass ich es verpasst habe, um ehrlich zu sein. Ich werde die UpdateControlsXXX() versuchen und sehen, ob ich sie zur Arbeit bringen kann. Danke nochmal, –

+0

Nun, die UpdateControlsXXX() funktioniert. Ich benutze Null als Parameter und benutze die Reihenfolge, in der Sie sie haben. Danke nochmal, @TomBrunberg –