Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Virtual-ListView Code gesucht (https://www.delphipraxis.net/145969-virtual-listview-code-gesucht.html)

Guido Eisenbeis 11. Jan 2010 17:07


Virtual-ListView Code gesucht
 
Mit Virtual-ListView meine ich ein normales ListView, das im virtuellen Modus benutzt wird, also OwnerData = True.

Das Thema Virtual-ListView ist recht komplex. Am Anfang dachte ich, ich nutze die VirtualTreeView-Komponente. Aber das wäre in dem von mir beabsichtigten Programm ein wenig überzogen. Ich will zum einen auf Fremdkomponenten verzichten, zum anderen lediglich nur ein paar ListView-Funktionen nutzen: Daten und CheckBoxes anzeigen und abfragen, und evtl. die Sortierfunktion.

Was ich mir wünsche, wäre eine Unit, die lediglich eingebunden werden muss, und die Funktionen bereitstellt, die dann an entsprechender Stelle aufgerufen werden. Zum Beispiel im OnData, eine Init- und eine Finalize-Routine, etc.

Ich arbeite nun schon ein paar Tage daran und sehe, dass (wie immer :mrgreen: ) eins zum anderen kommt und dann noch eins und noch eins. :cry: Und bevor ich nun doch das Rad neu erfinde, hier meine Frage: Hat schon jemand Code geschrieben, mit dem ein normales ListView als Virtual-ListView gehandhabt werden kann? Und würde die Früchte seiner Arbeit teilen? Würde mich freuen!

Guido.

Guido Eisenbeis 17. Jan 2010 22:02

Re: Virtual-ListView Code gesucht
 
Hallo McFly, ist jemand zu Hause? :bounce2:

Hat jemand vielleicht wenigstens einen Teil-Code?

Guido.

cookie22 18. Jan 2010 05:52

Re: Virtual-ListView Code gesucht
 
Liste der Anhänge anzeigen (Anzahl: 1)
hallo,

ich glaube das hilft dir weiter.

Delphi-Quellcode:
...
uses
VirtualListData;
...
private
  VirtualData: TVirtualData;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
  VirtualData := TVirtualData.Create(ListView1);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  VirtualData.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Item: TVirtualItem;
  i: Integer;
begin
  VirtualData.BeginUpdate;
  try
    for i := 0 to 200000 - 1 do
      begin
        Item := FVirtualData.Add;
        Item.Caption := 'irgendwas ' + IntToStr(i);
        Item.SubItems.Add(IntToStr(i));
        Item.SubItems.Add(IntToStr(i));
        Item.SubItems.Add(IntToStr(i));
      end;
  finally
    FVirtualData.EndUpdate;
  end;
end;
gruß,
cookie

Guido Eisenbeis 18. Jan 2010 13:59

Re: Virtual-ListView Code gesucht
 
Hallo Cookie,
ich kann nur sagen: Wow! :hello: Ich bin begeistert! :party:

Ich wurschtel da die ganze Zeit mit TStringList-Arrays rum und kam nicht richtig weiter. Dein Code ist für mich der richtige Ansatz. Ich hab ihn kurz ausprobiert und es funktionierte alles (was implementiert ist) einwandfrei.

In der nächsten Zeit werde ich mir den Code weiter zu Gemüte führen und sehen, was ich daraus machen kann. In meinem Code hatte ich schon die StateImages für die CheckBoxes integriert. Vielleicht kann ich Teile davon hierbei verwenden.

Auf jeden Fall bis hierhin vielen Dank für den Code! Der hilft mir tatsächlich weiter! :thumb:

Guido.

Guido Eisenbeis 18. Jan 2010 19:01

Re: Virtual-ListView Code gesucht
 
Um die StateImages für die CheckBoxes anzeigen zu können, ist es notwendig, dass der Aufruf von TVirtualData.Create zu einem Zeitpunkt erfolgt, an dem das Form mit dem ListView vollkommen sichtbar ist. Also z. B. im FromShow.

Normalerweise erstellt man Objecte im FormCreate, wenn sie während der kompletten Laufzeit des Programms benötigt werden. Wie könnte ich denn das handhaben, damit man hier nun das TVirtualData.Create im FormShow aufruft? Ich hab mir überlegt, eine Abfrage einzubauen, die dann einen Hinweis gibt. Also prüfen auf Form1.Visible, und falls nicht, eine Meldung ausgeben nach dem Motto "TVirtualData.Create in FormShow aufrufen!".

Aber so wirklich professionell scheint mir das nicht. Wie kann man das denn besser/galanter lösen?

Guido.

Edit: Außerdem müsste man im FormShow verhindern, dass die Instanz wieder und wieder überschrieben wird!? ... Also, das TVirtualData.Create im FormShow erscheint mir einfach ungeeignet.

cookie22 18. Jan 2010 22:42

Re: Virtual-ListView Code gesucht
 
warum in onshow und nicht in onactivate?

Guido Eisenbeis 19. Jan 2010 11:35

Re: Virtual-ListView Code gesucht
 
Zitat:

Zitat von cookie22
warum in onshow und nicht in onactivate?

Welchen Vorteil hätte das, bezogen auf den oben geschriebenen Zweck?

Dann noch eine Frage zu deinem obigen Tipp mit TCollection und TCollectionItem: Wie bist du denn auf diese Lösung gekommen? Ich hab mit TStringList versucht, die Items des ListViews zu handhaben. Das war wohl nicht der richtige Ansatz, denn Probleme gabs da einige. Zum Beispiel bei einer Sort-Funktion hatte ich noch keine Vorstellung, wie ich dann die Strings für die SubItems hanhaben sollte. Bei TCollectionItem übernimmt die Collection die Arbeit (glaube ich).

Zwei weitere Routinen seien des Dankes wegen auch erwähnt: TVirtualData.Update und TVirtualData.OnDataFind. Dass die im Code-Schnipsel drin sind, freut mich ebenfalls. Denn ich denke, um darauf zu kommen hätte ich einige Zeit gebraucht. Hast du den Code selbst entwickelt? Und hast du noch mehr davon? :mrgreen: *unersättlich-ich-bin*

Guido.

cookie22 20. Jan 2010 07:24

Re: Virtual-ListView Code gesucht
 
Zitat:

Zitat von Guido Eisenbeis
Zitat:

Zitat von cookie22
warum in onshow und nicht in onactivate?

Welchen Vorteil hätte das, bezogen auf den oben geschriebenen Zweck?

Dann noch eine Frage zu deinem obigen Tipp mit TCollection und TCollectionItem: Wie bist du denn auf diese Lösung gekommen? Ich hab mit TStringList versucht, die Items des ListViews zu handhaben. Das war wohl nicht der richtige Ansatz, denn Probleme gabs da einige. Zum Beispiel bei einer Sort-Funktion hatte ich noch keine Vorstellung, wie ich dann die Strings für die SubItems hanhaben sollte. Bei TCollectionItem übernimmt die Collection die Arbeit (glaube ich).

Zwei weitere Routinen seien des Dankes wegen auch erwähnt: TVirtualData.Update und TVirtualData.OnDataFind. Dass die im Code-Schnipsel drin sind, freut mich ebenfalls. Denn ich denke, um darauf zu kommen hätte ich einige Zeit gebraucht. Hast du den Code selbst entwickelt? Und hast du noch mehr davon? :mrgreen: *unersättlich-ich-bin*

Guido.

ka, hatte das in meiner code schnipsel sammlung, woher das kommt weiss ich net mehr.

zum thema sortieren kann ich dir folgendes anbieten:
Delphi-Quellcode:
unit SortCollections;

interface

uses classes;

type
  TSortableCollection = class(TCollection)
  protected
    function Compare(Item1, Item2 : TCollectionItem) : integer; virtual;
    procedure QuickSort(L, R: Integer);
  public
    procedure Sort;
  end;

implementation

type
  // Helper class to allow sorting of a TCollection
  {$HINTS OFF}
  TShadowedCollection = class(TPersistent)
  private
    FItemClass: TCollectionItemClass;
    FItems: TList;
  end;
  {$HINTS ON}


{ TSortableCollection }

function TSortableCollection.Compare(Item1, Item2: TCollectionItem): integer;
begin
(*

Descendant classes would override this method and cast Item1 and Item2 to the
decendant class's collection item type perform the field comparisions

if item1.MyField < item2.MyField
  return -1
else if item1.MyField > item2.MyField
  return 1
else return 0

*)
  result := 0;
end;

procedure TSortableCollection.QuickSort(L, R: Integer);
var
  I, J, p: Integer;
  Save: TCollectionItem;
  SortList: TList;
begin
  //This cast allows us to get at the private elements in the base class
  SortList := TShadowedCollection(Self).FItems;

  repeat
    I := L;
    J := R;
    P := (L + R) shr 1;
    repeat
      while Compare(Items[I], Items[P]) < 0 do
        Inc(I);
      while Compare(Items[J], Items[P]) > 0 do
        Dec(J);
      if I <= J then begin
        Save             := SortList.Items[I];
        SortList.Items[I] := SortList.Items[J];
        SortList.Items[J] := Save;
        if P = I then
          P := J
        else if P = J then
          P := I;
        Inc(I);
        Dec(J);
      end;
    until I > J;
    if L < J then
      QuickSort(L, J);
    L := I;
  until I >= R;
end;

procedure TSortableCollection.Sort;
begin
  if Count > 1 then
    QuickSort(0, pred(Count));
end;

end.
gruß,
cookie

Guido Eisenbeis 20. Jan 2010 20:39

Re: Virtual-ListView Code gesucht
 
Hallo cookie.

Vielen Dank für den Sortieren-Code! :hello: Ich versuche mal in den nächsten Tagen da durchzusteigen.

Bis dann denn,
Guido.

Guido Eisenbeis 26. Jan 2010 07:04

Re: Virtual-ListView Code gesucht
 
Hallo cookie,

bin noch nicht zum Sortieren-Code gekommen, denn ich hänge seit Tagen an der CheckBox-Darstellung (StateImages) die sind mal da, mal nicht. Komme nicht wirklich weiter.

Ich habe das OnMouseDown-Event in die TVirtualData-Klasse umgeleitet (und wieder zurück) und kann erfolgreich das Klicken auf den CheckBox-Bereich abfangen und den entsprechenden Wert an StateIndex zuweisen. Das klappt soweit. Was nicht klappt ist, wie gesagt, das Speichern der StateImages in ein TImageList.

Ich erzeuge das TImageList zur Laufzeit und will das auch so beibehalten. Zum Testen habe ich ein TImageList zur Designtime draufsetzt. Das funktioniert, wenn OwnerData auf False ist und erst zur Runtime auf True geschaltet wird. Und der Hammer ist, das funktioniert nur in der IDE. Wenn ich die Exe ohne die IDE starte, gehts wieder nicht.

Ich hab schon 1 Million Tests und WebSuchen durchgeführt. Da waren schon andere am Verzweifeln und haben recht obskure Anweisungen für die Reichenfolge beschrieben, die dann eher an Rituale erinnern. Zum Beispiel: "Zuerst muss du OwnerData ausschalten, dann das TImageList auf die Form setzen, ... vor dem Zuweisen an StateImages muss man OwnerData wieder einschalten, aber nur bei Vollmond!" :wink: Bisher funktioniert jedoch nichts zuverlässig. Ich bin für jeden Tipp dankbar!

Hast du dafür auch noch ein Code-Schnipsel? Würde mich freuen!

Ich freue mich natürlich auch, wenn jemand anders einen Tipp dazu hat.

Guido.


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:39 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