TListBox eindeutige Einträge erstellen.
-
Hallo,
ich lese aus einer Datenbank Namen aus.
Diese werden dann in 2 Listboxen im Format: "NACHNAME, VORNAME" angezeigt.
Wie kann ich nun herausfinden, welcher Eintrag in der Datenbank ausgewählt wurde?
Denn es kann ja sein, dass ein Name 2 mal in der Datenbank ist.Ich habe in der Datenbank einen primary key, "Id" genannt.
Kann ich den irgendwie versteckt an den Listboxeintrag ranhängen?
-
Listman schrieb:
Kann ich den irgendwie versteckt an den Listboxeintrag ranhängen?
Nein, das geht leider nicht, da AnsiString nicht über das, für so etwas sonst so nützliche Feld Tag verfügt.
Wenn die Reihenfolge in der ListBox nicht verändert wird, könntest Du ein int-Array erstellen, dass die IDs in der Reihenfolge erhält, in der die Namen in der ListBox stehen. Dieses Array könntest Du notfalls auch an die ListBox hängen (TListBox::Tag).
Aber, ich als User würde mich etwas verarscht fühlen, wenn ich zwei gleiche Einträge in der ListBox habe, zwischen denen kein Unterschied besteht.
Je nach Anweundungszweck würde ich den Namen nur einmal in der ListBox anzeigen und, bei Bedarf den User entscheiden lassen, welcher gemeint ist, indem man mehr Daten zu dem Eintrag anzeigt, sobald er ausgewählt wird. So was wie Ort, oder Telefonnr., oder sonst was. Kommt drauf an, welche Daten Du in der DB hast.
-
Hallo
Naja, immerhin kann über TListBox::Items::Objects zu jedem Listeintrag ein zusätzlicher versteckter Wert zugeordnet werden, sei es nun ein einfacher Integer-Index oder eine Speicheradresse eines Objektes außerhalb der Listbox.
bis bald
akari
-
Joe_M. schrieb:
Nein, das geht leider nicht, da AnsiString nicht über das, für so etwas sonst so nützliche Feld Tag verfügt.
Es gibt allerdings TStrings::Objects.
-
Danke, ich finde Die Idee mit dem Array ganz gut.
Ich hab aber noch nicht so mit arrays gearbeitet.
Daher meinte Frage: Wie definiere ich ein Array von variabler größe?
Die Anzahl der Einträge bekomme ich durch:
Query->RecordCountWie mache ich ein Array, welches genau diese größe hat?
-
Hallo
Wenn du wirklich ein eigenes Arrays aufbauen willst (Wie schon gesagt, ::Items::Objects bietet dir bereits ein passendes dynamisches Array mit automatisch richtiger Dimension), dann schau dir DynamicArray oder besser noch std::vector an. Dazu findest du über die Suchfunktion hier im Forum genug Beispiele.
bis bald
akari
-
Ich würde auch die andere Möglichkeit nehmen, mit dem bereits eingebauten Objekt.
Ich hab nur leider eine Ahnung, wie ich das machen kann
-
-
ahh, vielen Dank, das hat funktioniert
-
Hallo Listmann,
eine andere Möglichkeit als das parallele Ablegen:
Schreibe einfach Deine Daten komplett in die Listbox; setze zwischem den
angezeigten Text (also sichtbaren) und den zugehörigen Daten (also unsichtbar
für den User) ein beliebiges Trennzeichen z.B.
sichtbarer Text|unsichtbarer TextNun musst Du nur noch die Listbox auf Ownerdraw setzen und dort zeichnest
Du nur den Text bis zum Trenner. Fertig. Ein Vorteil dieser Methode: Du
kannst jederzeit mit einem Merker (bei mir immer eine Boolean oPrgComp)
z.B. zum Testen im IDE den unsichtbaren Text mit sichtbar machen. Ausser-
dem kannst Du ganz normal auf die Items und Methoden der Listbox zugreifen
und hast keinerlei Probleme bei Neusortierung, neuen Einträgen, gelöschten
Einträgen usw.:void __fastcall TForm3::frm3_lbK_Benutzer_ListeDrawItem(TWinControl *Control, int Index, TRect &ARect, TOwnerDrawState State) try { // Fehlerroutine Start Integer iPos; AnsiString zTxt,zName; TColor f1,f2; // Vars definieren TRect CRect; // vorbereiten TListBox *LBox; // vorbereiten LBox =frm3_lbK_Benutzer_Liste; // zuordnen zTxt =LBox->Items->Strings[Index]; // Text auslesen z.B. Admin (ID: 1)|unsichtbare Daten... iPos =zTxt.AnsiPos("|"); zName =zTxt.SubString(1,iPos-1); // Benutzername abschneiden LBox->Canvas->Brush->Color=clWhite; // Farbe HG festlegen LBox->Canvas->FillRect(ARect); // und Rahmen zeichnen if(Form1->oPrgComp) { zName=zTxt+" >>> "+zName; } // nur im IDE alles anzeigen ARect.Top+=1; ARect.Bottom-=0; ARect.Left=3; ARect.Right-=1; // Koords anpassen f1=clWhite; f2=clBlack; if(Odd(Index)) { f1=TColor(0x00EEEEEE); } // HG und VG Farben //if(State.Contains(odSelected)==true) { f1=clHighlight; f2=clHighlightText; } // Eintrag ist selektiert if(LBox->Enabled==false) { f1=TColor(0x00EEEEEE); f2=clGray; } // Control ist gesperrt LBox->Canvas->Brush->Color=f1; // Farbe HG festlegen LBox->Canvas->Font->Color =f2; // Farbe VG festlegen LBox->Canvas->FillRect(ARect); // und Rahmen zeichnen LBox->Canvas->TextRect(ARect,ARect.Left+4,(ARect.Top+ARect.Bottom-LBox->Canvas->TextHeight(zTxt))/2,zTxt); // Text schreiben if(State.Contains(odSelected)==true) { // Eintrag ist selektiert f1=clRed; // Rahmenfarbe CRect=Rect(ARect.Left,ARect.Top,ARect.Right-1,ARect.Bottom); // Koords übergeben LBox->Canvas->Brush->Color=f1; // Rahmenarbe LBox->Canvas->FrameRect(CRect); // Kasten aussenrum zeichnen } // ende if(State. } catch(Exception& e) { MessageBox(NULL, e.Message.c_str(), "TForm3::frm3_lbK_Benutzer_ListeDrawItem()", MB_OK); } // Fehler anzeigen }
Gruss Stefan
-
akari schrieb:
[...] immerhin kann über TListBox::Items::Objects zu jedem Listeintrag [...]
Oh je, da habt ihr natürlich recht, ::Objects hatte ich ganz vergessen.
Sorry
-
Hallo
Stefan7124 schrieb:
Ausser-
dem kannst Du ganz normal auf die Items und Methoden der Listbox zugreifen
und hast keinerlei Probleme bei Neusortierung, neuen Einträgen, gelöschten
Einträgen usw.:Hast du mit Items->Objects auch nicht.
bis bald
akari