Autor |
Beitrag |
galagher
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Sa 17.11.12 22:51
Hallo!
Naja, meine Frage steht ja schon im Titel!
Bei TListBox gibt's ja ItemIndex, ich brauche nun etwas Entsprechendes für eine TStringList.
Delphi-Quelltext 1: 2:
| for i := ListBox1.ItemIndex+1 to ListBox1.Items.Count-1 do |
Wie mache ich genau das mit TStringList? Wie erhalte ich den aktuellen Index?
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: Sa 17.11.12 23:03
Hallo,
galagher hat folgendes geschrieben : | Wie mache ich genau das mit TStringList? Wie erhalte ich den aktuellen Index? |
Was verstehst Du unter dem aktuellen Index einer Stringliste?
Nach meinem Kenntnisstand werden die Einträge nur über ihren Index angesprochen. Einen ausgewählten Eintrag im Sinne von itemindex gibt es nicht, also bleibt nur
Delphi-Quelltext 1: 2: 3: 4: 5:
| i:=anfangswert; repeat .... := stringlist[i]; inc(i); until i>stringlist.count-1; |
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
|
|
Gerd Kayser
      
Beiträge: 632
Erhaltene Danke: 121
Win 7 32-bit
Delphi 2006/XE
|
Verfasst: Sa 17.11.12 23:35
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 18.11.12 01:26
Vielleicht sollte man erst einmal klären, wovon der Index denn eigentlich sein soll, wir können ja schließlich nicht hellsehen. Möglicherweise ist TStrings.IndexOf gemeint, aber das kann ich aus der Frage auch nicht wirklich herauslesen.
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 18.11.12 10:15
Bei einer Listbox wird die Index-Variable ItemIndex "mitgeführt", weil die Listbox eine visuelle Komponente ist und "wissen" muß, welcher Eintrag den Fokus hat, um in als ausgewählt anzeigen zu können. ItemIndex ist aber kein Property der Stringlist TListBox.Items, sondern von TListBox. Das heißt, TListBox.Items, das ja eine StringList ist, besitzt kein solches Property, genauso wenig wie TStrings bzw. TStringList über ein solches Property verfügen. Wenn du mit einer TStringList arbeitest, mußt du mit einer eigenen Variablen dafür sorgen, daß der richtige Eintrag angesprochen wird.
Nehmen wir mal als Beispiel wieder eine TListBox, die auf deinem Hauptformular liegt. Der Anwender kann hier munter drauflosklicken und Einträge auswählen. Nun kannst du, z.B. für Anwendungsfenster, die keinen Zugriff auf dein Hauptformular haben, eine globale Integer-Variable in einer Unit deklarieren, auf die alle Forms Zugriff haben. Dieser Variablen weist du bei Änderungenn in deiner ListBox den Wert von ListBox.ItemIndex zu (über die Ereignisbehandlung OnChange deiner ListBox). So können jetzt die anderen Forms, die nicht direkt den ItemIndex deiner Listbox auslesen könnnen, dennoch wissen, welcher Eintrag gerade markiert ist.
Wenn du allerdings mit einer Stringliste arbeitest, gibt es keine Markierung eines bestimmten Eintrags, weil der Anwender ja gar nicht direkt auf diese Liste zugreifen kann.
Für diesen Beitrag haben gedankt: jaenicke
|
|
rushifell
      
Beiträge: 306
Erhaltene Danke: 14
|
Verfasst: So 18.11.12 11:05
Darum musst Du Dich in einer Stringlist selbst kümmern. Möglich wäre das z.B. über AddObject.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Var List:TStringlist; ... List.AddObject('Zeile',TObject(Integer(False)));
List.Objects[5]:=TObject(Integer(True));
i:=List.IndexOfObject(TObject(Integer(True)));
For i:=0 to List.Count-1 do IF Boolean(List.Objects[i]) then ShowMessage('Zeile '+IntToStr(i)+' ausgewählt'); |
Das lässt sich dann jedoch eher mit ListBox.Selected als mit ItemIndex vergleichen. Der benötigte Speicher wird hierbei wieder automatisch freigegeben (soweit ich weiss). Wenn's wirklich nur ein ausgewählter Eintrag sein soll, so würde ich eher eine zusätzliche Variable verwenden.
Viele Grüße
|
|
WasWeißDennIch
      
Beiträge: 653
Erhaltene Danke: 160
|
Verfasst: So 18.11.12 12:00
Da würde ich mir wohl eher eine Klasse mit so einem Index ableiten. Aber mir ist eh noch nicht ganz klar, wozu der eigentlich dienen soll.
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 18.11.12 19:22
Hallo!
Danke für die vielen Antworten!
Da es bei TStringList nichts gibt, was ItemIndex entspricht, wie ja auch Mathematiker schon sagte, habe ich nun eine globale Integer-Variable, der ich den benötigten Wert zuweise:
Perlsau hat folgendes geschrieben : | Wenn du mit einer TStringList arbeitest, mußt du mit einer eigenen Variablen dafür sorgen, daß der richtige Eintrag angesprochen wird. |
WasWeißDennIch hat folgendes geschrieben : | Möglicherweise ist TStrings.IndexOf gemeint, aber das kann ich aus der Frage auch nicht wirklich herauslesen. |
Nein, IndexOf erwartet ja einen String, den kenne ich aber nicht unbedingt!
Da TStringList grosse Dateien um ein Vielfaches schneller lädt als TListBox, verwende ich jetzt eine TStringList und nehme dafür in Kauf, die Integer-Variable selbst zu verwalten!
Danke!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 18.11.12 19:52
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 18.11.12 21:32
jaenicke hat folgendes geschrieben : | Es wäre sinnvoller, wenn du einfach mal kurz erklärst was du eigentlich machen möchtest, denn das liest sich nicht unbedingt als ob das eine gute Lösung ist... |
Es ist ein Karteikasten, die Daten werden in einer TStringList gehalten und verwaltet und in visuellen Komponenten (TJvEdit, TJvRichEdit) dargstellt. Jede "Karte" der Kartei hat eine Stichwortzeile, die in den JvEdit's angezeigt wird, und Text, den ich im JvRichEdit anzeige.
Ich stelle immer 10 "Karten" dar, daher brauche ich 10 JvEdit's und ein TJvRichEdit für den (RTF-formatierbaren) Text der vordersten Karte.
Es ginge sicher auch mit einem Array, aber ich verwende halt eine TStringList.
Eine TListBox hätte den Vorteil, dass man die "Karten" auch als Liste darstellen könnte und mit Mausklick auswählen kann.
Aber wie gesagt, TListBox ist zu langsam, wenn die Datendatei gross ist. Mit TStringList kann ich 10000 Datensätze in < 1 Sekunde laden.
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 18.11.12 21:58
galagher hat folgendes geschrieben : | jaenicke hat folgendes geschrieben : | Es wäre sinnvoller, wenn du einfach mal kurz erklärst was du eigentlich machen möchtest, denn das liest sich nicht unbedingt als ob das eine gute Lösung ist... | Es ist ein Karteikasten, die Daten werden in einer TStringList gehalten und verwaltet und in visuellen Komponenten (TJvEdit, TJvRichEdit) dargstellt. Jede "Karte" der Kartei hat eine Stichwortzeile, die in den JvEdit's angezeigt wird, und Text, den ich im JvRichEdit anzeige.
Ich stelle immer 10 "Karten" dar, daher brauche ich 10 JvEdit's und ein TJvRichEdit für den (RTF-formatierbaren) Text der vordersten Karte.
Es ginge sicher auch mit einem Array, aber ich verwende halt eine TStringList.
Eine TListBox hätte den Vorteil, dass man die "Karten" auch als Liste darstellen könnte und mit Mausklick auswählen kann.
Aber wie gesagt, TListBox ist zu langsam, wenn die Datendatei gross ist. Mit TStringList kann ich 10000 Datensätze in < 1 Sekunde laden. |
Wäre es da nicht besser, die Karteikarten-Texte, die ja RTF-formatiert angezeigt werden sollen, auch als RTF (d.h. incl. Formatierung) zu speichern und in der Stringliste lediglich die Dateinamen zu verwalten, und vielleicht zusätzlich in einer Listbox die Stichworte? Wenn du nämlich den Text aller Karteikarten in einer einzigen Stringlist verwaltest, kannst du pro RichEdit immer nur eine Zeile (bzw. einen Absatz) darstellen. Was, wenn der Anwender einen zweiten Absatz einfügen möchte?
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 18.11.12 22:06
Perlsau hat folgendes geschrieben : | Wäre es da nicht besser, die Karteikarten-Texte, die ja RTF-formatiert angezeigt werden sollen, auch als RTF (d.h. incl. Formatierung) zu speichern und in der Stringliste lediglich die Dateinamen zu verwalten |
Also, der Ansatz gefällt mir gar nicht! Nein, wenn, dann eine Datenbank (habe mich noch nie damit beschäftigt) oder eben eine Liste!
Perlsau hat folgendes geschrieben : | Wenn du nämlich den Text aller Karteikarten in einer einzigen Stringlist verwaltest, kannst du pro RichEdit immer nur eine Zeile (bzw. einen Absatz) darstellen. Was, wenn der Anwender einen zweiten Absatz einfügen möchte? |
sLineBreak wird einfach in ein besonderes, nur dafür reserviertes Zeichen konvertiert und dann als eine einzige Zeile in die Liste geschrieben. Beim Auslesen einfach wieder in sLineBreak zurückändern und da ist er, der Text, samt Formatierung und Zeilenumbrüchen!
Wenn man nun noch aus der RTF-Formatierung alles Überflüssige heraus nimmt (man braucht nicht wirklich alles!), wird das Ganze ein wenig kürzer. So funktioniert das!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
Perlsau
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 18.11.12 22:12
galagher hat folgendes geschrieben : | Perlsau hat folgendes geschrieben : | Wäre es da nicht besser, die Karteikarten-Texte, die ja RTF-formatiert angezeigt werden sollen, auch als RTF (d.h. incl. Formatierung) zu speichern und in der Stringliste lediglich die Dateinamen zu verwalten | Also, der Ansatz gefällt mir gar nicht! Nein, wenn, dann eine Datenbank (habe mich noch nie damit beschäftigt) oder eben eine Liste! |
Was gefällt dir denn daran nicht?
Ja, eine Datenbank wäre für deine Zwecke auf jeden Fall günstiger, allein schon wegen der Suche. Eine SQL-Suche ist um vieles schneller und performanter als eine Suche in einer Stringliste. Und laß dich ja nicht von der Bezeichnung "Datenbank" abschrecken, so schwer ist das nicht, wenn du bereits über ausreichende Programmiererfahrung verfügst.
galagher hat folgendes geschrieben : | Perlsau hat folgendes geschrieben : | Wenn du nämlich den Text aller Karteikarten in einer einzigen Stringlist verwaltest, kannst du pro RichEdit immer nur eine Zeile (bzw. einen Absatz) darstellen. Was, wenn der Anwender einen zweiten Absatz einfügen möchte? | sLineBreak wird einfach in ein besonderes, nur dafür reserviertes Zeichen konvertiert und dann als eine einzige Zeile in die Liste geschrieben. Beim Auslesen einfach wieder in sLineBreak zurückändern und da ist er, der Text, samt Formatierung und Zeilenumbrüchen!
Wenn man nun noch aus der RTF-Formatierung alles Überflüssige heraus nimmt (man braucht nicht wirklich alles!), wird das Ganze ein wenig kürzer. So funktioniert das! |
Damit ist dann aber der von dir so gerühmte Geschwindigskeitsvorteil wieder dahin ...
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: So 18.11.12 22:25
Perlsau hat folgendes geschrieben : | Was gefällt dir denn daran nicht? |
Die dutzenden, hunderten, tausenden Dateien, die dann im Anwerdungsdaten-Ordner sind! Ich meine, wenn schon, denn schon: Es soll schon möglich sein, pro Kartendatei mindestens 10000 Karten zu speichern! Das wären dann also 10000 Dateien. Brrr!
Perlsau hat folgendes geschrieben : | Ja, eine Datenbank wäre für deine Zwecke auf jeden Fall günstiger |
Ja, später, morgen, irgendwann einmal, ganz sicher, nur - also, jetzt, jetzt ist es grad ungünstig, weil...
Im Ernst: Für's erste vielleicht mal was ganz Einfaches, nur so zum Testen.
Perlsau hat folgendes geschrieben : | Damit ist dann aber der von dir so gerühmte Geschwindigskeitsvorteil wieder dahin ... |
Ist nicht so schlimm, es wird ja pro Karte nur 1x konvertiert, beim Blättern in der Kartei könnte ich das auch umgehen und nur den Kartentext konvertieren, den ich dann auch anzeigen lassen will, aber wie gesagt, es fällt nicht ins Gewicht!
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
bummi
      
Beiträge: 1248
Erhaltene Danke: 187
XP - Server 2008R2
D2 - Delphi XE
|
Verfasst: Mo 19.11.12 01:28
dann versuch mal das, das bringt ordentlich Tempo
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| private
FSL: TStringList; public end;
var Form5: TForm5;
implementation
{$R *.dfm}
procedure TForm5.Button1Click(Sender: TObject); begin FSL.LoadFromFile(YOURFILE); ListBox1.Count := FSL.Count; end;
procedure TForm5.FormCreate(Sender: TObject); begin FSL := TStringList.Create; ListBox1.Style := lbVirtual; end;
procedure TForm5.FormDestroy(Sender: TObject); begin FSL.Free; end;
procedure TForm5.ListBox1Data(Control: TWinControl; Index: Integer; var Data: string); begin Data := FSL[Index]; end; |
_________________ Das Problem liegt üblicherweise zwischen den Ohren H₂♂
DRY DRY KISS
|
|
galagher 
      
Beiträge: 2556
Erhaltene Danke: 45
Windows 10 Home
Delphi 10.1 Starter, Lazarus 2.0.6
|
Verfasst: Mo 19.11.12 20:04
_________________ gedunstig war's - und fahle wornen zerschellten karsig im gestrock. oh graus, es gloomt der jabberwock - und die graisligen gulpen nurmen!
|
|
|