BCB ListView Items per Maus sortieren



  • Hallo,
    nach 2 Tagen suchen und probieren suche ich nach einer Lösung ein Item von mehreren per Drag and Drop umzusortieren.

    ListView steht auf Report und DragMode auf Automatik. Die Events On StartDrag,DragDrop, DragOver sind mir bekannt. Folgendes habe ich in OnDragOver geschrieben:

    if (Source == ListView3)
       Accept = true;
       else
       Accept = false;
    

    Somit definiere ich die Drag and Drop Funktion nur innerhalb der ListView.
    In DragDrop habe ich ja die Objekte Sender Source, sowie die Koordinaten X,Y.

    Der einfache Aufruf

    ListView3->DragDrop(Source,X,Y);
    

    führt zu einer Zugriffsverletzung. Ich hab keinen Plan wie ich das gescheit lösen soll. Hat jemand von euch eine Idee wie ich weiter vorgehen soll?



  • Bitte noch nichts verraten....
    Ich schau mir erstmal die Funktionen
    ItemAtPos und ListView->Exchange noch
    mal genauer an wenn ich später zu Hause
    bin.



  • Die Annahme das die Listbox Methoden
    gleich der ListView Methoden ist war leider Falsch. Ich bekomme es einfach
    nicht hin. Um meinen Fehler zu verstehen
    und die Grundfunktion meines Vorhabens zu
    verstehen, habe ich mir einen Spin
    Button genommen und für SpinButtonUp folgenden Code geschrieben:

    //Letztes item bis zum Listenanfang verschieben auf SpineditUp Button.
    
    TListItem *item;
    TListItem *tempitem;
    
    int index = ListView3->Itemindex;
    
    if (index > 0)
    {
    tempitem = ListView3->Items->Item[index-1];
    item = ListView3->Items->Item[index];
    
    ListView3->Items->Item[index -1] = item;
    ListView3->Items->Item[index] = tempitem;
    
    ListView3->Items->Item[index]->Selected=false;
    ListView3->Items->Item[index-1]->Selected=true;
    }
    

    Wenn ich das letzte Item anklicke und
    per SpinButtonUp das Item nach oben
    verschieben möchte, wird jeder Eintrag mit dem zuerst ausgewähltem
    Item überschrieben ohne zu tauschen obwohl tempitem in index
    kopiert wird. Was mache ich da falsch???



  • Hallo Zero01,

    mit

    ListView3->Items->Item[index] = tempitem;
    

    ersetzt Du einen Eintrag.

    Du musst daher die Befehle

    ListView3->Items->Insert[index1,tempitem2];   // einfügen
    ListView3->Items->Delete[index2,tempitem1];   // löschen
    

    benutzen.

    Dann sollte es klappen 🙂

    Gruß Stefan



  • Warum denn delete?
    Ich möchte doch vertauschen solange
    bis das item einmal durch die ganze Liste
    gewandert ist, vom Ende bis zum Listenanfang. Ein Klick auf
    den Button switched das Item um
    eins nach oben ohne andere
    Items zu löschen.

    Edit: Wenn ich ohne Delete die beiden
    Items mit Insert vertausche sollte es
    doch gehen.



  • Hier stand Unsinn.



  • Hallo Zero01,

    mit Insert fügst du NEUE Einträge hinzu, d.h. die alten bleiben enthalten.

    Ein Beispiel:
    Du hast 10 Items und möchtest Pos.2 mit Pos. 8 tauschen.

    Du hast nun drei Möglichkeiten:
    a)
    Du liest Pos. 2 in einen AnsiString aus und setzt dann die Items direkt neu ein:

    string1=ListView->Items->Item[2];
    ListView->Items->Item[2]=ListView->Items->Item[8];
    ListView->Items->Item[8]=string1;
    

    oder Möglichkeit b)

    string1=ListView->Items->Item[2];
    string2=ListView->Items->Item[8];
    ListView->Items->Delete(2);
    ListView->Items->Delete(8);
    ListView->Items->Insert(2,string2);
    ListView->Items->Insert(8,string1);
    

    oder Möglichkeit c)

    string1=ListView->Items->Item[2];
    string2=ListView->Items->Item[8];
    ListView->Items->Add(string1);
    ListView->Items->Add(string2);
    

    Welche Möglichkeit Du nimmst, hängt davon ab, ob Deine Listview z.B. sortiert ist oder ob Du z.B. zwischen den Vorgängen die Items noch prüfen/verändern willst.

    Gruß Stefan



  • Hallo Stefan!

    Danke für deine Hilfe! Zuhause werde ich
    das mal testen und berichten. Die Möglichkeit einfach nur die Strings
    zu tauschen, habe ich wegen den
    Subitems gelassen. Ich versuche
    mal den Tausch mit delete und insert

    btw: nimmt deine Variante b auch
    die Subitems mit?

    Edit2: b geht doch gar nicht. man kann
    keinem String ein TItem zuweisen.



  • Hallo Zero01

    habe das von ListBox abgeleitet; bei ListView sollte es mit den Subitems aber ähnlich gehen (testen konnte ich es nicht, da ich unterwegs bin 🙂 )

    Benutze immer StringGrids statt Listview, da wesentlich flexibler und einfacher. Von den Listviews bin ich weg, da mit den Subitems zu aufwendig.
    Beim StringGrid gibt es nur Zeilen und fertig.

    Gruß Stefan



  • Das macht nichts, hast mir trotzdem sehr geholfen - Danke

    Ich probier gleich mal zu Hause die Methode mit der Brechstange



  • Juhuuu, habs endlich hinbekommen. Da die Anzahl der Subitems in meinem Projekt eh Fix ist bin ich den Weg über die Strings gegangen. Mit Delete und Insert
    ballerten mir Zugriffsverletzungen um die Ohren. Jetzt kann ich das alles schön
    mit den DragDrop Events verbinden und den Kram per Maus verschieben.

    ItemAtPos(X,Y) oder TPoint.x...y.. ist dann eine sehr schöne Funktion für den gegenwärtig gewählten Index.

    int index = ListView3->ItemIndex;
    
      if (index > 0)
    
     {
         //tempitem  index - 1
         String a =  ListView3->Items->Item[index-1]->Caption;
         String b =  ListView3->Items->Item[index-1]->SubItems->Strings[0];
         String c =  ListView3->Items->Item[index-1]->SubItems->Strings[1];
    
         //item index
         String d = ListView3->Items->Item[index]->Caption;
         String e = ListView3->Items->Item[index]->SubItems->Strings[0];
         String f = ListView3->Items->Item[index]->SubItems->Strings[1];
    
         //tempitem  index - 1
         ListView3->Items->Item[index-1]->Caption = d;
         ListView3->Items->Item[index-1]->SubItems->Strings[0] = e;
         ListView3->Items->Item[index-1]->SubItems->Strings[1] = f;
    
         //item index
         ListView3->Items->Item[index]->Caption = a;
         ListView3->Items->Item[index]->SubItems->Strings[0] =  b;
         ListView3->Items->Item[index]->SubItems->Strings[1] =  c;
    
         ListView3->Items->Item[index]->Selected = false;
         ListView3->Items->Item[index - 1]->Selected = true;
     }
    

    In die andere Richtung geht es bis ListView->Items->Count - 1 und einfach
    umgekehrten Indexberechnungen. Is zwar ein bissl Spaghetticode aber seis drum


Anmelden zum Antworten