AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Virtual-ListView Code gesucht

Ein Thema von Guido Eisenbeis · begonnen am 11. Jan 2010 · letzter Beitrag vom 26. Jan 2010
Antwort Antwort
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#1

Virtual-ListView Code gesucht

  Alt 11. Jan 2010, 17:07
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 ) eins zum anderen kommt und dann noch eins und noch eins. 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.
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#2

Re: Virtual-ListView Code gesucht

  Alt 17. Jan 2010, 22:02
Hallo McFly, ist jemand zu Hause?

Hat jemand vielleicht wenigstens einen Teil-Code?

Guido.
  Mit Zitat antworten Zitat
Benutzerbild von cookie22
cookie22

Registriert seit: 28. Jun 2006
Ort: Düsseldorf
936 Beiträge
 
Delphi XE2 Professional
 
#3

Re: Virtual-ListView Code gesucht

  Alt 18. Jan 2010, 05:52
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
Angehängte Dateien
Dateityp: zip virtuallistdata_206.zip (2,0 KB, 188x aufgerufen)
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#4

Re: Virtual-ListView Code gesucht

  Alt 18. Jan 2010, 13:59
Hallo Cookie,
ich kann nur sagen: Wow! Ich bin begeistert!

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!

Guido.
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#5

Re: Virtual-ListView Code gesucht

  Alt 18. Jan 2010, 19:01
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.
  Mit Zitat antworten Zitat
Benutzerbild von cookie22
cookie22

Registriert seit: 28. Jun 2006
Ort: Düsseldorf
936 Beiträge
 
Delphi XE2 Professional
 
#6

Re: Virtual-ListView Code gesucht

  Alt 18. Jan 2010, 22:42
warum in onshow und nicht in onactivate?
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: Virtual-ListView Code gesucht

  Alt 19. Jan 2010, 11:35
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? *unersättlich-ich-bin*

Guido.
  Mit Zitat antworten Zitat
Benutzerbild von cookie22
cookie22

Registriert seit: 28. Jun 2006
Ort: Düsseldorf
936 Beiträge
 
Delphi XE2 Professional
 
#8

Re: Virtual-ListView Code gesucht

  Alt 20. Jan 2010, 07:24
Zitat von Guido Eisenbeis:
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? *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
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#9

Re: Virtual-ListView Code gesucht

  Alt 20. Jan 2010, 20:39
Hallo cookie.

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

Bis dann denn,
Guido.
  Mit Zitat antworten Zitat
Guido Eisenbeis

Registriert seit: 9. Apr 2006
389 Beiträge
 
Delphi 10.3 Rio
 
#10

Re: Virtual-ListView Code gesucht

  Alt 26. Jan 2010, 07:04
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!" 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.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 16:52 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf