ListView-Items kopieren (war: 8NUB92)



  • Hallo zusammen,
    ich habe ein TListView, in dem ich (Multiselect=true) mehrere Zeilen per checkbox auswählen kann. Auf diese will ich nun zugreifen, um diese
    a) in ein anderes ListView zu schreiben (also kopieren)
    b) zu löschen, und zwar als Dateien von der Platte.

    Das ListView hat 3 Spalten. 1 für die Checkboxes, 2 für Dateinamen, 3 für den Pfad.

    Ich weiss, das ListView hat einen Index, über den man prüfen kann, welche checkboxes welcher Zeilen ausgewählt (also gecheckt) wurden und welche nicht. Aber wie komme ich an die Inhalte der Spalten ran und welche Formate haben diese (zum übergeben an Variablen).

    Ich hab auch mit "SelectionCopy(TObject*, Destination)" die markierten Inhalte zu kopieren, aber irgendwie krieg ich das nicht so ganz auf die Reihe. Vielleicht kann mir ja jemand helfen, ich wäre sehr dankbar!!! Markus

    Edit:
    Bitte aussagekräftige Überschriften wählen. Danke!

    [ Dieser Beitrag wurde am 08.07.2003 um 10:57 Uhr von Jansen editiert. ]



  • nun wie b) geht weiß ich noch nicht genau aber wenn ichs rausfinde sag ichs dir
    du brauchst 2 listitems (li1, li2) und 2 listviews (lv1, lv2)
    wenn du auf Button1 Clickst wird jede datei mit einem häckchen aus dem lv1 in das lv2 geschrieben... bei vielen dateien achte bitte darauf: das kann länger dauern...

    (aber vorher noch ein hinweis: die erste spalte brauchst du nicht, weil die checkbox keine extra spalte benötigt, deshalb ist der text der 1. Spalte immer leer... aber ich habe den quelltext jetzt trotzdem so gemacht, dass die 1. spalte leer ist)

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
      TListItem* li1;                        //Listitems deklarieren
      TListItem* li2;   
    
      for (int i=0; i<lv1->ItemsCount; i++)  //Listbox durchlaufen
      {
        li1=lv1->Items->Item[i];             //li1 wird der i-ten zeile zugewiesen
        if (li1->Checked)                    //wenn gecheckt
        {
          li2=lv2->Items->Add();             //in 2. listview zeile hinzufügen
          li2->Caption=li1->Caption;         //1. spalte->Text wird zugewiesen
                                             //(wie gesagt ist diese spalte leer
          li2->SubItems->Add(li1->SubItems->Strings[1];  //2. Spalte
          li2->SubItems->Add(li1->SubItems->Strings[2];  //3. Spalte
        }
      }
    }
    


  • zu a)

    TListItem *Item1 = ListView1->Selected;
      TListItem *Item2;
      while (Item1)
      {
        Item2 = ListView2->Items->Add();
        Item2->Caption = Item1->Caption;
        Item2->SubItems->Assign(Item1->SubItems);
        Item1 = ListView1->GetNextItem(Item1, sdAll, TItemStates() << isSelected);
      }
    

    Im Unterschied zur Variante von tobeast werden hier nur die selektierten Items durchlaufen.

    zu b) sieh dir TListItem::SubItems in der Hilfe an, um dich über den Variablentyp und Möglichkeiten des Zugriffs zu informieren.



  • Vielen Dank für die Tips.
    Das Prinzip des Zugriffs ist mir nun klar.

    @Jansen: Eine (dumme ?) Verständnisfrage noch:
    Du schreibst, Deine Variante durchläuft nur die selektierten Items. Somit dürfte m.E diese auch schneller sein. Aber irgendwie muss hier doch auch rausgefunden werden, welche gecheckt sind und welche nicht.
    Ich vermute mal, das wird durch "TListItem *Item1 = ListView1->Selected;" und
    "Item1 = ListViewExe->GetNextItem(Item1, sdAll, TItemStates() << isSelected);" erledigt. Aber es müssen doch auch alle geprüft werden. Oder sind "nur" die mitgelieferten Routinen schneller als Tobeast's Schleife ?

    P.S.: Sorry für die nicht aussagekräftige Überschrift !! Kann es sein, dass ich die ganz vergessen habe ?? Kommt nicht wieder vor. Sorry !

    [ Dieser Beitrag wurde am 08.07.2003 um 20:37 Uhr von Markus Pelloth editiert. ]



  • Original erstellt von Markus Pelloth:
    Oder sind "nur" die mitgelieferten Routinen schneller als Tobeast's Schleife ?

    Absolut. Bei 100 zufällig ausgewählten Items aus einem ListView mit 10000 Items insgesamt benötigt GetNextItem() ca. 40 ms, mit der Variante von tobeast dauert es rund 2800 ms.

    Athlon 1600+/512MB | nur Items, keine SubItems kopiert.



  • Alles klar.
    Dann brauch ich eigentlich nur noch einen kleinen Tip, wie ich Deine Variante so umschreiben kann, damit er die abgehakten Checkboxen erkennt. Mit mehreren Zeilen markieren klappts wunderbar. Ich will aber, dass die einzelnen Einträge, und das können bis zu 500 sein, per Checkbox ausgewählt werden können, weil bei der Menge einmal mit str+klick daneben und Du kannst (als normaler User) meistens wieder von vorne anfangen.

    @tobeast: Bei Deienr Variante bekomme ich eine Fehlermeldung: Listenindex überschreitet das Maximun (2). Die Liste hat 43 Einträge. Weisst Du, was da faul ist ?



  • Original erstellt von Markus Pelloth:
    Ich will aber, dass die einzelnen Einträge, und das können bis zu 500 sein, per Checkbox ausgewählt werden können

    Dann bleibt nichts übrig, als tatsächlich jedes Item auf Checked zu prüfen.

    Aber bist du sicher, dass an deinem Programmdesign nicht grundsätzlich etwas faul ist? Welcher Mensch soll denn bis zu 500 Checkboxen abhaken?

    Was das ListIndex-Problem betrifft: dafür benutzt man den Debugger und geht den Code schrittweise durch. Offensichtlich hast du kein zweites SubItem.



  • Welcher Mensch soll denn bis zu 500 Checkboxen abhaken?

    Äääh, darüber sollte man sich tatsächlich Gedanken machen. Wahrscheinlich keiner. Da hast Du allerdings Recht.
    Dann werde ich Deine Lösung realisieren und dazu 2 ListViews nebeneinander setzen mit Hinzufügen- und Entfernen-Pfeil (wie bei Outlook-Verteilerlisten Mitglieder hinzufügen/entfernen). Ist auch übersichtlicher.
    Vielen Dank nochmal !!

    Was das ListIndex-Problem betrifft: dafür benutzt man den Debugger und geht den Code schrittweise durch. Offensichtlich hast du kein zweites SubItem.

    Das hab ich auch gemacht. Ein 2. SubItem hab ich auch. Aber egal. Bringt mich jetzt nicht weiter, wenn ich da nachbohre.

    [ Dieser Beitrag wurde am 08.07.2003 um 22:40 Uhr von Markus Pelloth editiert. ]


Anmelden zum Antworten