Struct in ListBox einbinden
-
Hallo.
Ich habe ein Problem:Bei mir in der ListBox stehen unterschiedliche Strings aus einer Tabelle. Diese Strings gehören jeweils zu unterschiedlichen ID's. Jetzt möchte ich die ID's der ausgewählten einträge herausfinden.
Ich habe gehört, dass dies mit einem Struct möglich ist, welches man mit in die Lisbox einbindet. Ich weiß aber nicht, wie das gehen soll.
In der Hilfe steht zwar:void __fastcall AddItem(AnsiString Item, TObject AObject);Aber ich weiß nicht wie ich das anwenden soll und wie ich dann hinterher aus den ausgewählten Einträgen die ID herausfinden kann.
Bitte helft mir.
MfG
Muecke
-
Hallo
die korrekte Methode ist
TListBox->Items->AddObject(const AnsiString S, System::TObject* AObject);damit hat der Eintrag einen festen Verweis auf ein Objekt, das du durch das Array
TListBox->Items->Objects[<Index>];wieder ermitteln kannst, wobei Index immer dem Index des Strings entspricht.
Zu beachten ist, das Items nicht für das Löschen der verbundenen Objekte zuständig ist.Du hast allerdings das Problem, das du structs verwendest, die du nicht an AddObject übergeben kannst. Dazu brauchst du von TObject abgeleitete Instanzen.
bis bald
akari
-
Ich muss nicht unbedingt ein Struct verwenden.
Was würdest du mir denn da vorschlagen...?
Noch habe ich das nicht in ein Struct geschrieben...MfG
Muecke
-
Hallo
Das kommt natürlich darauf an, was du mit dem Objekt machen willst. Da du etwas von ID gesagt hast, erstelle ich mal ein Beispiel.
Zuerst brauchst du eine von TObject abgeleitete Klasse (Achtung Minimallösung):
class TID : public TObject { public : AnsiString Caption; int ID; TID() : TObject() {}; };Aus dieser Klasse erstellst du nun deine Liste von relevanten Instanzen, die jeweils passende Werte enthalten. Diese packst du z.B. in ein Array. Jetzt kannst du die ListBox füllen :
for (int Lv = 0; Lv < ArrayCount; Lv++) ListBox->Items->Add(Array[Lv]->Caption; Array[Lv]);Jetzt kann die ListBox z.B. sortiert werden, ohne das du denn Bezug zur ID verlierst. Brauchst du jetzt die ID eines ListBox-Eintrags, machst du
TID *CurrID = static_cast<TID *> (ListBox->Items->Objects[ListBox->ItemIndex]);was in diesem Fall das Objekt des ausgewählten Eintrags bestimmt
bis bald
akari
-
Danke für die guten Beschreibungen. Zwei Probleme habe ich aber noch:
- Wie erstelle ich das Array basierend auf der Klasse?
- In meiner ListBox können mehrere Einträge ausgewählt sein. Wie kriege ich die ID von allen ausgewählten???
MfG
Muecke
-
Hallo
Wie erstelle ich das Array basierend auf der Klasse?
Da gibt es mehrere Möglichkeiten. Am besten in deinem Fall ist TObjectList, mit der Eigenschaft OwnsObjects auf true.
Das Array sollte natürlich als Membervariable des entsprechenden Forms deklariert werden, und im Konstruktor des Forms erstellt und im Destruktor gelöscht werden.In meiner ListBox können mehrere Einträge ausgewählt sein. Wie kriege ich die ID von allen ausgewählten???
Dazu gehst du mit dem Array ListBox->Selected alle Einträga durch und extrahierst bei true das ID-Objekt.
bis bald
akari
-
Ich habe das jetzt so deklariert. Ein globales Array;
TID Test[10];Das füllen der ListBox und des Arrays mache ich so:
while(!DatenmodulDB->IBQuery->Eof && i<10) { Test[i].kriterium = DatenmodulDB->IBQuery->Fields->Fields[1]->AsString; Test[i].id = DatenmodulDB->IBQuery->Fields->Fields[0]->AsInteger; LB_kriterien->Items->AddObject(Test[i].kriterium, &Test[i]); DatenmodulDB->IBQuery->Next(); i++; }Mir gefällt jetzt aber nicht, dass ich das Array statisch habe. Wäre gut wenn das eine dynamische größe hätte. Außerdem bekomme ich eine Fehlermeldung beim beenden des Programms:
Zugriffsverletzung bei Adresse ...
Wie kann ich das noch verbessern?
MfG
Muecke
-
Ihr würdet mir vielleicht auch schon helfen, wenn ihr mir sagt,
wie ich bestimmen kann, an welcher Position meine markierten Einträge stehen.
Das ich einfach den Index bekomme wo der Eintrag an der Position steht.MfG
Muecke
-
Hallo
Mir gefällt jetzt aber nicht, dass ich das Array statisch habe. Wäre gut wenn das eine dynamische größe hätte. Außerdem bekomme ich eine Fehlermeldung beim beenden des Programms:
Genau deshalb habe ich TObjectList geschrieben.
Ich zeig dir mal, wie ich das mir vorstelle :
Im Header des betreffenden Forms machst du diese Änderungen :// alle anderen Includes #include <memory> #include <contnrs.hpp> ... // hier Klassendefinition von TID ... class TForm1 : public TForm { ... private: // Anwender-Deklarationen ... // auto_ptr ist eine Erweiterung des normalen Raw Pointers, der die Lebenszeit // der angegeben Instanz beschränkt (in diesem Fall des Forms), so das du dich // nicht selber um das Löschen kümmern must std::auto_ptr<TObjectList> IDList; public: // Anwender-Deklarationen }In der Implementation des Forms schreibst du noch dazu
[cpp]// Konstruktor des Forms, um die ObjektList ergänzt
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner), IDList(new TObjectList)...
// Ein ID-Objekt soll erstellt werden und an die Liste angefügt werden
TID *NewID = new TID();
NewID->id = 1;
NewID->kriterium = "Record 1";
IDList->Add(NewID);
...
// Die Einträge der IDList sollen in der ListBox angezeigt werden.
// In diesem Fall einfach alle, allerdings ist es ohne Probleme möglich,
// in der Schleife noch eine Auswahl zu machen
for (int Lv = 0; Lv < IDList->Count; Lv++)
{
TID *CurrID = static_cast<TID *> (IDList->Items[Lv]);
LB_kriterien->Items->AddObject(CurrID->kriterium, CurrID);
}// Das Bestimmen des ausgewählten ID-Objects steht bereits oben
[/cpp]
Das mag vielleicht kompliziert und unnötig aussehen, ist aber sehr praktisch, wenn man die Möglichkeiten von OOP und VCL wirklich ausnutzt.bis bald
akari
-
Ok.
Ichj werde es mal versuchen.
Ich weiß aber nicht ob ich das hinkriege. Habe auch schon einen anderen Lösungsweg gefunden.MfG
Muecke