AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

VirtualTreeView und icons

Ein Thema von Wishmaster · begonnen am 9. Aug 2014 · letzter Beitrag vom 28. Aug 2014
Antwort Antwort
Seite 1 von 2  1 2      
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#1

VirtualTreeView und icons

  Alt 9. Aug 2014, 09:30
Hi.

ist es möglich in der virtual-treeview icons zu zeichnen ohne die "TImageList" zu verwenden?
ich habe eine große DB und jeder eintrag in der DB hat seinen eigenen icon.
die der benutzer ändern/löschen oder neue hinzufügen kann;

zurzeit lade ich eine externe Datei mit ~300 Icons in die "TImageList" und in der DB wird nur der index zum icon Gespeichert. was sehr limitiertend ist.



thx.
Miniaturansicht angehängter Grafiken
passman.jpg  
  Mit Zitat antworten Zitat
Whookie

Registriert seit: 3. Mai 2006
Ort: Graz
445 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: VirtualTreeView und icons

  Alt 9. Aug 2014, 11:29
Kenne mich mit VTV nicht wirklich aus, aber du kannst doch zur Laufzeit immer neue Images zu einer ImageList hinzufügen und dann ist es egal wann und von wo das eigentliche Icon her kommt...
Whookie

Software isn't released ... it is allowed to escape!
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#3

AW: VirtualTreeView und icons

  Alt 9. Aug 2014, 22:51
du hast recht, das problem ist allerdings das die ImageList kann nur eine limitierte anzahl von icons halten
wenn ich mich korrekt erinnere sind das ~500 Icons.


ps. ich habe auch nicht so viel erfahrung mit der VTV! so wenn jemand eine code schnipsel hat, ich wäre euch dankbar.
  Mit Zitat antworten Zitat
nuclearping

Registriert seit: 7. Jun 2008
708 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

AW: VirtualTreeView und icons

  Alt 9. Aug 2014, 22:57
Du kannst in den OnAfterCellPaint und OnBeforeCellPaint selbst Inhalte über den Parameter TargetCanvas in die Zelle(n) zeichnen.

Statt einer TImageList kannst du zB eine TList nehmen, da die Icons als TBitmaps ablegen und dann über einen der genannten Events selbst zeichnen, je nachdem, "wann" du das Icon haben willst.
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#5

AW: VirtualTreeView und icons

  Alt 9. Aug 2014, 23:40
wie schon gesagt ich habe auch nicht so viel erfahrung mit der VTV.
und korrigiere mich wenn ich falsch liege
aber ist es nicht sinnvoll/möglich die icons direkt in den Node Record abzuspeichern, genau wie den text.
ich denke dann braucht man auch keine listen für die icons.

Delphi-Quellcode:
  PRNodeData = ^TRNodeData;
  TRNodeData = record
   ID : Int64; // pointer
   Title : Widestring;
   Value : Widestring;
   Hiden : Boolean;
   Image : TBitmap; // icon
  end;

ich denke mein problem ist mehr das ich nicht genau weiß wie ich das zeichnen
soll. ich meine den text nach rechts verschieben und vor dem Text die box für das icon zeichnen soll.
ich verstehe die theorie dahinter. nur die umsetzung ins praktische, da hakt es noch.

ich glaube ich brauche ein Red Bull
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#6

AW: VirtualTreeView und icons

  Alt 10. Aug 2014, 02:03
Hab ich zwar noch nie versucht, kann mir aber gut vorstellen, daß dann das Handling des VirtualTreeViews um etliches langsamer wird, weil ja bei jedem Zugriff auf NodeData zusätzlich das Bitmap kopiert werden muß. Mit TImageList müssen die Bitmaps dagegen nur einmal kopiert werden, nämlich zwischen BeginUpdate und EndUpdate.

Auch hatte ich noch nie einen Fall, der es nötig machte, mehr als 500 Bitmaps bzw. Icons in einem VTV einzusetzen.
Miniaturansicht angehängter Grafiken
vtvbitmaps.jpg  
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#7

AW: VirtualTreeView und icons

  Alt 10. Aug 2014, 02:19
OK! ich habe es geschaft (Nach dem Red Bull ) so ich hatte recht mit der idee die icon direkt in den NodeRecord zu schreiben!
so jetzt ist der limit nur der arbeitsschpeicher.

so this is my solution! Have fun with it.

Delphi-Quellcode:
type
  PRNodeData = ^TRNodeData;
  TRNodeData = record
   ID : Int64; // pointer
   Title : Widestring;
   Value : Widestring;
   Hiden : Boolean;
   Image : TBitmap; // icon
  end;

procedure TMain_form.RecordTreeBeforeCellPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  CellPaintMode: TVTCellPaintMode; CellRect: TRect; var ContentRect: TRect);
var
 Data : PNodeData;
 R : TRect;
begin
  if Assigned(Node)then
   begin
     Data:= FolderTree.GetNodeData(Node);
    if Data^.Colored then
     begin
      case Column of
       0 :
        begin
         TargetCanvas.Brush.Color := $00FFFAF4;
         TargetCanvas.FillRect(CellRect);

        // Draw Icon Test

         R.Left:= ContentRect.Left-16;
         R.Top:= ContentRect.Top -1;
         R.Right:= ContentRect.Bottom + R.Left;
         R.Bottom:= ContentRect.Bottom -1;

         //TargetCanvas.Brush.Color:= clred;
         TargetCanvas.FillRect(R);

         TargetCanvas.Draw(R.Left, 0, Data^.Image); // Icon

        end;
       1 :
        begin
         (* Draw Gradient *)
         GradientFillHorizontal(TargetCanvas, CellRect, $00FFFAF4, clWhite, 100)
        end;
       2 :
        begin
         // comment todo
        end;
      end;


     end;
   end;
end;
ganz vergessen zu sagen, ich benutze eine leere TImageList um den text nach rechts zu bewegen




in meinem test lade ich die icons direkt von der festplatte
später wird das direkt von der DB/Stream geladen!

Delphi-Quellcode:
 Data:= RecordTree.GetNodeData(Parent);
 ...
 Data^.Image:= TBitmap.Create;
 Data^.Image.LoadFromFile('c:\...\...\folder_open.bmp');
 Data^.Image.Transparent := True;
 Data^.Image.TransparentMode := tmAuto;
nochmal danke an alle.

Geändert von Wishmaster (10. Aug 2014 um 02:37 Uhr)
  Mit Zitat antworten Zitat
Wishmaster

Registriert seit: 14. Sep 2002
Ort: Steinbach, MB, Canada
301 Beiträge
 
Delphi XE2 Architect
 
#8

AW: VirtualTreeView und icons

  Alt 10. Aug 2014, 03:27
@Perlsau

normalerweise würde ich dir zustimmen. in meinem fall ist es ein wenig anders,
bei meinem Programm erstellt der benutzer die DB/File und die felder Dynamisch.
so was ist wenn der benutzer 20000 einträge hat? und in jedem eintrag einen anders icon haben will.
wenn ich die Icons vorab in die TImageList Lade und nur den index in die DB speicher,
kann es später zum problem werden. sagen wir mal ich muss ein icon löschen/ändern (aus rechtlichen grunden,...)
so beim nächsten programm update stimmen die icons nicht mit dem eintrag überein
da der index zu den icon sich geändert hat. oder man macht die DB/Datei komplett mit einem anderen Programm auf.

ein anderer fall, was ist wenn du den folder mit deinen icons in die Virtual TreeView einlesen wilst
zum beispiel ich habe 1,148,532 icons auf meinem Computer das sind ~10 GB
ich glaube da versagen die meisten listen.

Datenbankgröße 32 TB (auch durch Dateisystem und Betriebssystem begrenzt)

und ich glaube der speed unterschied ist nicht so groß.



thx.
  Mit Zitat antworten Zitat
Perlsau
(Gast)

n/a Beiträge
 
#9

AW: VirtualTreeView und icons

  Alt 10. Aug 2014, 09:46
Daß in deinem Fall die Kapazität der TImageList nicht ausreicht, ist nachvollziehbar. Dennoch würde ich im NodeDataRecord nicht das eigentliche Bitmap speichern, sondern eine Id auf eine Liste bzw. auf die entsprechenden der DB-Bildtabelle. Ob du jetzt im Node selbst das Icon austauschst oder in der Liste macht im Grunde keinen Unterschied – abgesehen davon, daß nicht bei jedem Zugriff auf den Data-Record das Bitmap aus dem Speicher gekramt werden muß, denn das wird ja nur einmal beim Aufbau des Baums benötigt.

Das mit der Geschwindigkeit hab ich jetzt nicht mit einem TreeView ausprobiert, aber mit Datenbanken. Wenn ich z.B. eine Tabelle, die zwei Blob-Felder (ein Bitmap und ein RTF-Text) beinhaltet, sortiere, ist das ohne diese beiden Blob-Felder entsprechend schneller: Je mehr Datensätze in der Tabelle, desto größer der Geschwindigkeitsvorteil. Die benötigten Felder lasse ich dann aus einer zweiten Tabelle nach Bedarf selektieren (z.B. im AfterScroll-Ereignis). Mit anderen Worten: Da ich die beiden Blob-Felder nur zur Anzeige, nicht aber zur Anwendung von Such- und Sortierkriterien benötige, muß ich die nicht mitschleppen. Aus diesem Grund gibt es bei vielen Komponenten wie z.B. auch beim VTV die beiden Schalter BeginUpdate und EndUpdate.

Meine Bilder im dargestellten VTV kommen ebenfalls aus einer Datenbank und sind zudem ziemlich groß. Beim Baumaufbau werden diese Bitmaps, die an anderer Stelle in Originalgröße benötigt werden, mit StretchDraw in die Bitmaps der TImageList kopiert, wonach letztere dann dem VTV zugewiesen wird.
  Mit Zitat antworten Zitat
Aviator
Online

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#10

AW: VirtualTreeView und icons

  Alt 10. Aug 2014, 13:25
Dennoch würde ich im NodeDataRecord nicht das eigentliche Bitmap speichern, sondern eine Id auf eine Liste bzw. auf die entsprechenden der DB-Bildtabelle.
Da ich auch sehr viel mit Images und dem VTV arbeite, würde ich es ebenfalls so machen wenn mir eine ImageList nicht ausreichen würde. Der Vorteil ist nicht nur der Speicher, der pro Bild nur einmal belegt wird und nicht mehrfach pro Node, sondern sobald du die Liste mit den Bilder aktualisierst bzw. ein Bild austauschst, musst du nur den VTV mit VTV.Invalidate bzw. VTV.InvalidateNode(ANode) neu zeichnen lassen und die Bilder sind direkt auf dem neuen Stand.

Zitat von Wishmaster:
ganz vergessen zu sagen, ich benutze eine leere TImageList um den text nach rechts zu bewegen
Diesen Umweg würde ich nicht gehen, sondern ich würde im PainText Event des VTV den Text manuell um die Breite des betreffenden Images bewegen. Die Breite wird wohl immer gleich sein bzw. die könntest du auch dann aus der entsprechenden Liste auslesen. Für die Liste würde sich vielleicht dann schon eine eigene Klasse anbieten, in der noch zusätzliche Informationen zum Bild abgelegt werden können wie eben z.B. die Breite und die Höhe des Bildes.

Dann kannst du ganz einfach im PaintText Event per Index auf die Liste der Bilder zugreifen und dann um die Breite des Bildes verschieben.

Das mal so aus meiner Sicht. Vielleicht hilft es dir ja weiter.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:19 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz