[gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

[gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von mulcheo »

Hallo,

ich habe mal wieder eine Frage. Bei der Umsetzung der Tipps aus dem Forum habe ich mich nun dafür entschieden, meine Daten in einem Filestream abzulegen. Ich möchte im nächsten Schritt für jedes Datenset, das ich im Stream habe, ein Item in einer Listbox anlegen. Das funktioniert soweit ganz gut: ich lese den Stream schrittweise aus und lege jedesmal, wenn ein Set fertig ausgelesen ist, ein Item in der Listbox an (wobei der Name sich eben nach dem Daten im Stream richtet)... Das erste Item der Listbox entspricht dann dem ersten Datenset, das zweite dem zweiten etc.. Anschließend möchte die items der Listbox alphabetisch ordnen, doch dann entspricht mein erstes Item eben nicht mehr dem ersten Eintrag im Stream sondern, Eintrag Nummer XYZ.

Ich denke mal, ihr versteht, was ich meine... Gibt es beim Anlegen der Items Listbox.Items.Add(string); eine Möglichkeit, jedem Item auch eine Variable zuzuweisen, die mir später die Zuordnung ermöglicht, so dass ich beipielsweise erkennen kann, dass in der sortierten Listbox das 10te Item dem unsortierten Item Nummer 35 und damit dem Stream-set #35 entspricht?

als Lösung fällt mir bislang nur ein, am Ende des string (Listbox.Items.Add(string);) eine Nummer zu verstecken, die ich dann später auslese... aber das scheint mir sehr unelegant zu sein.

Wie immer schonmal Danke im Voraus :)
Zuletzt geändert von mulcheo am Di 12. Aug 2014, 22:46, insgesamt 1-mal geändert.

Michl
Beiträge: 2511
Registriert: Di 19. Jun 2012, 12:54

Re: Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von Michl »

Wenn Du keine ID im String darstellen willst, wäre eine Möglichkeit das TObject zu nutzen. In diesem Fall wird ein Record mit einem Integer hinter den Pointer versteckt. Man könnte natürlich auch auf andere Datentypen zeigen oder eben ein TObject bzw. dessen Nachfahren (mit möglicherweise ziemlichen Overhead) verwenden:

Code: Alles auswählen

type
  TMyRec = record
    i: Integer;
  end;
  PMyRec = ^TMyRec;
...
procedure TForm1.Button1Click(Sender: TObject);
var
  P: PMyRec;
begin
  new(P);                                      //Neues Record erstellen
  P^.i:=ListBox1.Items.Count + 1;
  ListBox1.AddItem('Ein ListBoxItem', TObject(P));
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
var
  i: Integer;
begin
  for i:=ListBox1.Items.Count-1 downto 0 do
    Dispose(PMyRec(ListBox1.Items.Objects[i]));  //Records wieder frei geben
end;
 
procedure TForm1.ListBox1Click(Sender: TObject);
var
  P: PMyRec;
begin
  P:=PMyRec(ListBox1.Items.Objects[ListBox1.ItemIndex]);
  ShowMessage('ListBoxItem Nr. '+IntToStr(P^.i)+' geklickt');
end;
Allerdings musst Du immer, wenn Du ein Item löschst, auch das Record bei dem Item mit freigeben.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection;  

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: [gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von mulcheo »

mhmmm, also danke für die Antwort, die auch sicher funktioniert. Da ich jedoch keine Ahnung von Pointern habe, habe ich mich letztlich doch für record-array entschieden, das mir hilft, string und integer zuzuordnen.

Scotty
Beiträge: 768
Registriert: Mo 4. Mai 2009, 13:24
OS, Lazarus, FPC: Arch Linux, Lazarus 1.3 r44426M FPC 2.6.4
CPU-Target: x86_64-linux-qt/gtk2
Kontaktdaten:

Re: [gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von Scotty »

Statt eines einfachen Pointers kannst du auch eine Klasse nehmen - und dort beliebige Methoden und Properties haben.

Code: Alles auswählen

type TMyClass=class;
 
aClass:=TMyClass.Create;
ListBox1.AddItem('Ein ListBoxItem', aClass);
 
aClass:=TMyClass(ListBox1.Items.Objects[ListBox1.ItemIndex]);
 
TMyClass(ListBox1.Items.Objects[i]).Free;

MmVisual
Beiträge: 1581
Registriert: Fr 10. Okt 2008, 23:54
OS, Lazarus, FPC: Winuxarm (L 4 FPC 3.2.2)
CPU-Target: 32/64Bit

Re: [gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von MmVisual »

Ich nutze die Objekte meist in Zusammenhang mit Datenbanken.

Die Datenbank-Tabelle hat je Datenzeile eine eindeutige ID Zahl, ist eine einfache Integer Zahl.

Code: Alles auswählen

ListBox1.AddItem(Query.FieldByName("Bezeichnung").AsString, TObject(Query.FieldByName("ID").AsInteger));
Somit, wenn man auf den Eintrag klickt, weiß ich auch welche Datenzeile der Tabelle gemeint ist:

Code: Alles auswählen

iID := Integer(ListBox1.Items.Objects[n]);
Also ich missbrauche dieses zusätzliche Pointer Feld um irgend eine Integer Zahl mir zu merken.
EleLa - Elektronik Lagerverwaltung - www.elela.de

Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2808
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: [gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von m.fuchs »

MmVisual hat geschrieben:Also ich missbrauche dieses zusätzliche Pointer Feld um irgend eine Integer Zahl mir zu merken.
Es ist gut, dass du das Wort "missbrauchen" dafür verwendest. Warum sowas nicht unbedingt eine gute Idee ist, habe ich schon mal dargelegt: http://www.lazarusforum.de/viewtopic.php?t=7595&p=67320
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: [gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von mulcheo »

[update]:
es hat mal wieder seine Zeit gebraucht, bis ich mich als Einsteiger in die Syntax einarbeiten konnte, aber die Lösung von scotty war letztlich genau, was ich suchte!

für alle Nachfolgenden evtl. hilfreich: meine Idee war, für ein Array (bei mir das Array der Klasse TKasten) eine Liste anzulegen, die jedem Element einen string zuordnet und diesen dann in einer _sortierten_ Listbox ausgibt. Der Clou ist, dass troz der Sortierung die Zuordnung des Listboxeintrages zum Element des Array Kasten erhalten bleibt :)

Zuweisung:

Code: Alles auswählen

for i:=Low(Kasten) to High(Kasten) do begin
  (...)
  ListBox1.AddItem(s, Kasten[i]);
end;
wobei Kasten definiert ist als:

Code: Alles auswählen

type
  TKasten = class
    AnfangsZeile: integer;
    (...)
  end;
 
var 
  Kasten: array of TKasten;
wenn ich nun auf die hinter dem Listeneintrag stehenden Werte zugreifen möchte sieht das beispielsweise so aus:

Code: Alles auswählen

procedure TForm2.ListBox1SelectionChange(Sender: TObject; User: boolean);
var
  i: integer;
  Verweis: TKasten;
 
begin
  Verweis:=Tkasten(ListBox1.Items.Objects[ListBox1.ItemIndex]);
  edit1.Text:=IntToStr(Verweis.AnfangsZeile);
end; 
Zuletzt geändert von mulcheo am Di 19. Aug 2014, 22:33, insgesamt 1-mal geändert.

Komoluna
Beiträge: 565
Registriert: So 26. Aug 2012, 09:03
OS, Lazarus, FPC: Windows(10), Linux(Arch)
CPU-Target: 64Bit

Re: [gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von Komoluna »

Code: Alles auswählen

procedure TForm2.ListBox1SelectionChange(Sender: TObject; User: boolean);
var
  i: integer;
  Verweis: TKasten;
 
begin
  Verweis:=TKasten.Create;   //Das ist nicht nötig
  Verweis:=Tkasten(ListBox1.Items.Objects[ListBox1.ItemIndex]);
  edit1.Text:=IntToStr(Verweis.AnfangsZeile);
  (...)
  Verweis.Free;  //Das auch nicht
end; 
Du weist 2 mal Verweis einen Wert zu:
• eine neue Instanz(TKasten.Create)
• das Objekt, was in der Listbox gespeichert wird

Dabei wird das neu erstellte Objekt überschrieben, und das in der Listbox gespeicherte freigegeben.

MFG

Komoluna
Programmer: A device to convert coffee into software.

Rekursion: siehe Rekursion.

mulcheo
Beiträge: 57
Registriert: Do 1. Aug 2013, 15:11

Re: [gelöst] Items einer Listbox an Werte koppeln (o.ä.)

Beitrag von mulcheo »

habe ich auch gerade beim testen gemerkt (Speicherkonflikte und tot) ... ist nun berichtigt, danke ^^

Antworten