Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   TStringList einer TListBox zuweisen (https://www.delphipraxis.net/170930-tstringlist-einer-tlistbox-zuweisen.html)

Peter-Pascal 10. Okt 2012 20:20

TStringList einer TListBox zuweisen
 
Hallo,

ich bin ein wenig ratlos, bzw. hoffe das mir das jemand erklären kann.

Ich habe eine TStringList (Liste := TStringList.create) und möchte diese einer TCheckListBox zuweisen in der Annahme, dass mir der Inhalt ausgewiesen wird.
CheckListBox1.Items := Liste;
Alles was ich später in Liste schreibe wird nicht in der CheckListBox aufgeführt.

Weise ich meiner Variablen Liste (deklariert als TStringList) := CheckListBox1.Items zu, dann funktioniert es. Kann es sein, dass glaube ich hier mal gelesen zu haben, dass nur eine Kopie im vorherigen Falle benutzt wird? Es als quasi zwei Listen gibt?

Ich nutze die Object-Eigenschaft der TStringList (Liste.AddObject('Neuer Eintrag',TObject.create); und wollte über die CheckListbox auch die Objecte verändern,in der Annahme auch die zugewiese Liste hat den gleichen Inhalt.

Vielen Dank für Eure Hilfe

Gruß Peter

himitsu 10. Okt 2012 20:33

AW: TStringList einer TListBox zuweisen
 
Tja, da die TListBox, bzw. TCheckListBox, so wie z.B. auch ein TMemo, ihre eigenen ganz "speziellen" Listen besitzen und es absichtlich nicht zulassen, daß man diese austauscht/kaputtmacht, wird dieser "Schreibzugriff" anders behandelt.

Aber ein Blick in die Quellcodes hätte es einem auch selbst verraten, also daß es im Setter etwas Anders behandelt wird. :angle2:
Delphi-Quellcode:
CheckListBox1.Items.Assign(Liste);


Und TStrings.Assign macht
Delphi-Quellcode:
CheckListBox1.Items.Clear;
CheckListBox1.Items.AddStrings(Liste);

Peter-Pascal 10. Okt 2012 20:37

AW: TStringList einer TListBox zuweisen
 
Ich muss zugeben bislang noch nicht in den Quellcode geschaut zu haben, bin ich bislang noch nie so richtig durchgestiegen.

Aber es klappt doch, wenn ich es umgekehrt zuweise, also der Liste die Items aus ChecklistBox?

himitsu 10. Okt 2012 21:05

AW: TStringList einer TListBox zuweisen
 
Du mußt unbedingt den Unterschied zwischen einem Property und einer Variable lernen.

Nochmals:

Beim Zuweisen an TListBox.Items wird ein Setter aufgerufen und darin wird der Inhalt (alle Strings) von der Einen in die andere Stringliste kopiert.

Wenn du deiner Variable umgekehrt den TListBox.Items zuweist, dann speicherst du nur den Instanzzeiger der Stringliste in deiner Variable.
PS: Du hast dir grade ein Speicherleck gebastelt, denn die TStringList, welche vorher in der Variable "verlinkt" war, fliegt nun spurlos und verloren im Speicher rum.

Peter-Pascal 10. Okt 2012 21:28

AW: TStringList einer TListBox zuweisen
 
Zitat:

Zitat von himitsu (Beitrag 1186571)

Wenn du deiner Variable umgekehrt den TListBox.Items zuweist, dann speicherst du nur den Instanzzeiger der Stringliste in deiner Variable.
PS: Du hast dir grade ein Speicherleck gebastelt, denn die TStringList, welche vorher in der Variable "verlinkt" war, fliegt nun spurlos und verloren im Speicher rum.

Genau diese Zuweisung wollte ich ja, denn so kann ich von zwei Stellen auf die gleiche Liste zugreifen. Oder gibt es eine andere Möglichkeit?

Reicht es nicht, der Variablen Nil zuzuweisen, um das Speickerleck zu beseitigen? TListBox.Items wird von TListBox aus dem Speicher entfernt

himitsu 10. Okt 2012 21:52

AW: TStringList einer TListBox zuweisen
 
Zitat:

Zitat von Peter-Pascal (Beitrag 1186574)
Genau diese Zuweisung wollte ich ja, denn so kann ich von zwei Stellen auf die gleiche Liste zugreifen.

Wenn es nur darum geht, dann würde das so schon funktionieren.
Du brauchst vorher nur keine TStringList zu erstellen und in die Variable zu legen.

Zitat:

Zitat von Peter-Pascal (Beitrag 1186574)
TListBox.Items wird von TListBox aus dem Speicher entfernt

Jupp.

Zitat:

Zitat von Peter-Pascal (Beitrag 1186574)
Reicht es nicht, der Variablen Nil zuzuweisen, um das Speickerleck zu beseitigen?

Wenn du vorher eine selbsterzeugte TStringList dort reingetan hast, dann nicht, denn um die Freigabe dieser Instanz müsstest du dich kümmern.

Peter-Pascal 10. Okt 2012 22:10

AW: TStringList einer TListBox zuweisen
 
die Variable ist nur vom Typ TStringList, wird nicht vorher erzeugt. Klappt aber leider doch nicht so schön, wie erhofft. Ich hatte mir dadurch Übersichtlichkeit versprochen. Leider ist das Gegenteil der Fall.

Vielen Dank für Deine Hilfe, himitsu.

Gruß Peter

Bummi 10. Okt 2012 22:29

AW: TStringList einer TListBox zuweisen
 
Ich weiß ja nicht was Du genau vor hast, aber gegf. ist
lbVirtual beim Style der Checklistbox das was Du suchst (die Checkistbox hat dann keine eigen Liste sondern stellt Daten aus einer Stringlist, einem Array oder was auch immer dar), mit den Ereignissen OnData und OnDataObject, die Frage ist nur wie Du die Checked-Eigenschaft verwalten willst.

Peter-Pascal 11. Okt 2012 08:21

AW: TStringList einer TListBox zuweisen
 
Hallo Thomas,

die Sache mit lbVirtual habe ich mir angeschaut und ich muss zugeben auf den ersten Blick als zu kompliziert beiseite gelegt. Nichtsdestotrotz möchte ich gerade den vollen Leistungsumfang der CheckListBox haben.

Wozu ich es brauche:

Ich habe mehrere tief verschachtelte selbstgebaute Objecte. In einem Object wird eine Liste (TStringList) geführt, die Objecte und Namen entgegen nimmt. Hier habe ich mich für TStringList entschieden statt TObjectList, gerade weil ich die Liste weitergeben wollte. Und in der CheckBoxList müssen alle Namen angezeigt werden.
Um das ständige synchronisieren zweier Listen zu vermeiden, habe ich diese Zuweisung vorgenommen von TCheckListBox.Item an eine Variable vom Typ TStringList. Das klappt auch. Ich kann entweder über die CheckListBox zugreifen oder über die StringList in meinem Object. Ist aber doch nicht so elegant wie ich es gehofft habe. Greife ich über TCheckListBox.Item zu, muss ich immer eine TypCast machen: TObject(TCheckListBox.Item.Object[i]).
Zur vollständigkeit: Im anderen Falle muss ich natürlich auch einen TypCast durchführen, kann mir aber ein Property schreiben, das mir genau das gewünschte Object liefert.

Ich denke ich werde hier noch viele Fragen stellen. Wobei ich vieles auch in den bisherigen Beiträgen gefunden habe.

Gruß Peter

Bummi 11. Okt 2012 08:36

AW: TStringList einer TListBox zuweisen
 
Klingt so als ob Du Dir die Genrics mal anschauen könntest, mit lbVirtual könntest Du für die Check-Infos direkt eine Property Deiner Objekte vorsehen.

Peter-Pascal 11. Okt 2012 11:57

AW: TStringList einer TListBox zuweisen
 
Was heißt Genrics?

Ich sehe gerade Du arbeitest mit Delphi XE3, weißt Du ob in dieser Version die TRibbon verbessert wurden? In hatte in einem anderen Beitrag schon danach gefragt, weil ich bei XE2 große Probleme mit TRibbon habe.

Bummi 11. Okt 2012 12:05

AW: TStringList einer TListBox zuweisen
 
Generics wäre in Deinem Fall z.B. eine Liste TObjectList<TMyClass> ...
Die delphieigene Ribbonimplementierung verwende ich nicht (stattdessen devExpress)

Peter-Pascal 11. Okt 2012 12:52

AW: TStringList einer TListBox zuweisen
 
Ja die Empfehlung für devExpress habe ich hier bereits bekommen, aber da ich noch nicht so richtig weiß, wo die Reise hingeht, möchte ich noch kein Geld ausgeben und hoffe halt darauf, dass XE3 die TRibbon verbessert hat. Es ist von der Anlage her soweit ja ganz gut, funktioniert nur nicht, das wird man ja wohl in den Griff bekommen...

Popov 11. Okt 2012 14:13

AW: TStringList einer TListBox zuweisen
 
Vielleicht noch einen kleinen Tipp:

Delphi-Quellcode:
  ListBox1.Items.Text := List.Text;

Bummi 11. Okt 2012 14:43

AW: TStringList einer TListBox zuweisen
 
@Popov

Zitat:

Ich nutze die Object-Eigenschaft der TStringList

Popov 11. Okt 2012 16:03

AW: TStringList einer TListBox zuweisen
 
Ok, habe ich überlesen.

himitsu 11. Okt 2012 16:12

AW: TStringList einer TListBox zuweisen
 
Zitat:

Zitat von Popov (Beitrag 1186663)
Vielleicht noch einen kleinen Tipp:

Delphi-Quellcode:
  ListBox1.Items.Text := List.Text;

Kommt auf's Selbe raus, wie

Delphi-Quellcode:
ListBox1.Items := List;
// oder
ListBox1.Items.Assigned(List);

Wobei der Weg über .Text eines TStrings nicht unbedingt optimal ist (außer z.B. bei aktuellen TMemo und TRichEdit), denn was passiert intern?
Es wird, beim Auslesen von .Text, aus allen einzelnen Strings ein ganz großer String gemacht, welcher dann, beim Zuweisen an .Text, erst wieder zerlegt und dann jeder einzelstring an die Komponente übergeben wird.

Bummi 11. Okt 2012 16:29

AW: TStringList einer TListBox zuweisen
 
@himitsu

nicht wirklich, die Objektreferenzen sind bei .Text weg ....

Popov 11. Okt 2012 16:48

AW: TStringList einer TListBox zuweisen
 
Himitsu, du hast wahrscheinlich Recht. Und wenn man ehrlich ist sollte man alles was richtig gemacht werden kann auch immer richtig machen. Trotzdem unterscheide ich immer wieder etwas auf die Schnelle machen und "richtig" machen. Soll heißen: nicht jedes kleine Tool das man programmiert muß optimiert sein.

Wobei
Delphi-Quellcode:
  ListBox1.Items.Assigned(List);
  //
letztendlich und hauptsächlich auch nur auf
Delphi-Quellcode:
  ListBox1.Items.Clear;
  for i := 0 to List.Count - 1 do
    ListBox1.Items.AddObject(List[i], List.Objects[i]);
hinausläuft.

himitsu 11. Okt 2012 16:51

AW: TStringList einer TListBox zuweisen
 
Na guuuut.

Aber er wollte ja eh die beiden Stringlisten Variablen/Property synchron halten,
also letztendlich mit Beidem auf die selbe Liste (die der TListBox oder bei einer virtuellen ListBox die andere Liste) zugreifen.

(OK, man könnte auch in den entsprechenden OnChange-Ereignissen die Änderungenjeweils in die andere Liste übertragen. Aber wozu die Mühe, wenn man einfach die selbe Liste nutzen kann)

Peter-Pascal 12. Okt 2012 10:50

AW: TStringList einer TListBox zuweisen
 
Zitat:

Zitat von himitsu (Beitrag 1186684)

Aber er wollte ja eh die beiden Stringlisten Variablen/Property synchron halten,
also letztendlich mit Beidem auf die selbe Liste (die der TListBox oder bei einer virtuellen ListBox die andere Liste) zugreifen.

(OK, man könnte auch in den entsprechenden OnChange-Ereignissen die Änderungenjeweils in die andere Liste übertragen. Aber wozu die Mühe, wenn man einfach die selbe Liste nutzen kann)

Genau das ist mein Ziel, statt zwei Listen zu synchronisieren, die Adressen auszutauschen und von zwei Orten darauf zuzugreifen. Einmal aus einem Object und zum Zweiten durch TCheckListBox.

Die Liste wird Visualisiert, der Anwender kann wählen und durch ItemIndex habe ich den ausgewählten Punkt und directen Zugriff auf das Object.

Nochmal vielen Dank an alle für die Hilfe.


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:23 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz