Richtiger wäre es den ganzen Kram zu trennen.
Es gibt eine Liste mit Datenobjekten
Delphi-Quellcode:
// ein Datenobjekt
TImageData = class
property Filename : string;
end;
Für das DatenObjekt gibt es eine Form, die dieses DatenObjekt anzeigen kann
Delphi-Quellcode:
TImageView = class( TDockForm )
property ImageData : TImageData;
end;
Die MainForm kann nun aus der Liste mit den DatenObjekten die passenden Forms erzeugen und natürlich auch wieder entfernen.
Delphi-Quellcode:
TMainForm = class( TForm )
FDataList : TObjectList;
FViewList : TObjectList;
procedure PresentDataList;
end;
procedure TMainForm.PresentDataList;
var
LView : TImageView;
begin
for LIdx := 0 to FDataList.Count - 1 do
begin
if LIdx < FViewList.Count then
LView := FViewList[LIdx] as TImageView
else
begin
LView := TImageView.Create( PageControl1 );
FViewList.Add( LView );
LView.ManualDock( PageControl1, nil, alClient );
end;
LView.Visible := false;
LView.ImageData := FDataList[LIdx] as TImageData;
LView.Visible := true;
end;
// überflüssige Views entfernen
for LIdx := FViewList.Count - 1 downto FDataList.Count do
begin
LView := FViewList[LIdx] as TImageView;
FViewList.Delete( LIdx );
LView.Close;
end;
end;
Nach jeder Änderung an der
FDataList
(Sortieren, Hinzufügen, Entfernen) ruft man einfach
PresentDataList
auf und der Keks ist gegessen.
Auf der MainForm ist nun ein Button um das aktuell angezeigte Bild zu entfernen, dann muss man folgendes ausführen
Delphi-Quellcode:
procedure TMainForm.Button1Click( Sender : TObject );
begin
FDataList.Delete( PageControl1.TabIndex );
PresentDataList;
end;
Richter wäre es aber auch hier eine sprechendere Programmierung zu wählen
Delphi-Quellcode:
procedure TMainForm.Button1Click( Sender : TObject );
begin
RemoveCurrentItem;
end;
procedure TMainForm.RemoveCurrentItem;
begin
RemoveItem( FDataList[PageControl1.TabIndex] );
end;
procedure TMainForm.RemoveItem( AItem : TObject );
begin
FDataList.Remove( AItem );
PresentDataList;
end;
Wenn man nämlich aus der ImageView heraus dieses Entfernen auslösen möchte, dann gibt man jeder ImageView einfach dieses als Event mit
Delphi-Quellcode:
procedure TMainForm.PresentDataList;
...
LView.OnRemoveItem := RemoveItem;
...
und in der ImageView wird das dann einfach aufgerufen und alles passiert von selber
Delphi-Quellcode:
procedure TImageView.RemoveButtonClick( Sender : TObject );
begin
OnRemoveItem( ImageData );
end;
Das möchte ich jetzt aber nicht weiter ausführen, sonst sprengt es den Rahmen.
Die
TImageView
Form muss jetzt natürlich im
OnShow
Event die Daten aus dem
ImageData
lesen und entsprechend anzeigen. Hier kann man in dem Setter von ImageData auch noch ein Flag setzen, ob sich ImageData überhaupt geändert hat und kann sich das erneute Einlesen sparen.
(da das mit dem Resourcenschutzblock nur zu Verwirrung führt, habe ich mal alles weggelassen, was nicht unbedingt notwendig ist)