Einzelnen Beitrag anzeigen

Perlsau
(Gast)

n/a Beiträge
 
#12

AW: VirtualTreeView und icons

  Alt 12. Aug 2014, 03:44
Selbstverständlich mußt du das Icon erst mal aus der Datenbank einlesen. Mit deiner Methode, das Icon in NodeData zu speichern, verursachst du unnötige CPU-Last beim Handling mit dem VTV, was natürlich bedeutet, daß der Aufbau eines riesigen Trees wie in deinem Fall unnötig verzögert wird. So müssen z.B. die Bitmaps in NodeData beim Umsortieren ständig mitkopiert werden, was bei einer externen Liste (Generics TObjectList) nicht nötig wäre, denn die hättest du einfach nur nach dem Index sortiert, damit das gesuchte Bitmap schnell gefunden wird.

Dazu erzeugst du dir erstmal eine Klasse:
Delphi-Quellcode:
UNIT Startbilder;

INTERFACE

USES
  ExtCtrls, StdCtrls, Classes, Graphics;

TYPE
  TStartBild = Class

    PRIVATE { Private-Deklarationen }
      Var
        fBild : TImage;
        fIndex : Integer;
        
      Function GetfBild : TImage;
      Procedure SetfBild(Const Value : TImage);
      Function GetfIndex : TImage;
      Procedure SetfIndex(Const Value : TImage);

    PUBLIC { Public-Deklarationen  }

      Constructor Create();
      Destructor Destroy; override;

      Property Bild : TImage read GetfBild write SetfBild;
      Property Index : Integer read GetfIndex write SetfIndex;

  END;

IMPLEMENTATION
{ TStartBild }

Function TStartBild.GetfBild: TImage;
begin
  Result := fBild;
end;

Procedure TStartBild.SetfBild(Const Value: TImage);
begin
  fBild.Assign(Value);
end;

Function TStartBild.GetfIndex: Integer;
begin
  Result := fBild;
end;

Procedure TStartBild.SetfIndex(Const Value: Integer);
begin
  fBild.Assign(Value);
end;

Constructor TStartBild.Create;
begin
  inherited;
  fBild := TImage.Create(nil);
  fBild.Visible := False;
  fBild.AutoSize := False;
  fBild.Stretch := False;
  fBild.Proportional := False;
  fBild.Center := False;
  fBild.Width := 30; // oder wie die Größe deiner Icons eben ist
  fBild.Height := 30;
end;

Destructor TStartBild.Destroy;
begin
     fBild.Free;
  inherited;
end;

end.
Dann deklariest du in der Formular-Unit, die den VTV aufnehmen soll, eine Objektliste:
Delphi-Quellcode:
  ...
  PRIVATE { Private-Deklarationen }
    Var
      BList : Generics.Collections.TObjectList<TStartBild>;
  ...
In FormCreate und FormDestroy deines VTV-Formulars schreibst du:
Delphi-Quellcode:
Procedure TFormMain.FormCreate(Sender: TObject);
begin
  BList := TObjectList<TStartBild>.Create;
  ...
end;

Procedure TFormMain.FormDestroy(Sender: TObject);
begin
  If BList.Count > 0 Then
  BList.DeleteRange(0,BList.Count-1);
  BList.Free;
  ...
end;
Den VTV baust du in einer privaten Methode auf, die z.B. bei Programmstart aufgerufen wird. Dort gehst du deine DB-Tabelle durch und liest die entsprechenden Spalten aus. In NodeData.Index schreibst du den Index deiner Tabelle, der mit dem Index in BList korrespondiert (nicht der Listen-Index, sondern der Eintrag Index, der in der Klasse festgelegt wurde).

Nachtrag:

Probier's doch einfach mal aus: Erstelle eine Exe mit den Icons in NodeData und eine mit den Icons in einer Objektliste, wobei du jedesmal die Zeit mißt, die vergeht, wenn du
  • den Baum aufbaust
  • den Baum sortierst
  • im Baum suchst.

Geändert von Perlsau (12. Aug 2014 um 04:03 Uhr) Grund: Nachtrag
  Mit Zitat antworten Zitat