Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#18

AW: TImages verwalten

  Alt 15. Okt 2014, 15:22
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)
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat