TListBox

Grundlegendes
Der Inhalt einer TListBox Komponente
ist vergleichbar mit
TStringList, also Strings in mehreren Zeilen.
Die Aufzählung der Zeilen beginnt
mit 0, also die erste Zeile ist 0 die zweite Zeile 1 die dritte
Zeile 2 und so weiter... Eine Zeile wird in Delphi als Items
bezeichnet. Jede einzelne Zeile (Items) für sich betrachtet ist
ein String Ergo, ListBox1.Items[0]
ist die erste Zeile der ListBox 1 "und quasi ein String",
demzufolge gelten auch alle Operationen die für einen String
gelten >
siehe Stringoperationen. Tausche dazu einfach das "S" in den
Beispielen durch ListBox1.Items[X]
(wobei
X die Zeile der ListBox ist).
Länge des Textes in einer
TListBox-Zeile (Items)
ermitteln >
siehe Stringoperationen
Inhalt eines in einer
TListBox-Zeile (Items)
zurechtschneiden >
siehe Stringoperationen
Nach einem Zeichen oder
Teilstring in einer TListBox-Zeile (Items) suchen >
siehe Stringoperationen
Zuweisen von Text (
var S:
String;)
| |
ListBox1.Items.Add ('ich
bin ein ListBoxItem');
oder ListBox1.Items.Add(S); |
Auslesen
einer Zeile
(
var S:
String;)
| |
Edit1.Text := ListBox1.Items[0]
// liest den Inhalt der ersten Zeile in Edit1
S
:= ListBox1.Items[1]
// liest den Inhalt der zweiten Zeile in die Variable S |
Zuweisen einer Zahl (
var Zahl: Integer;
Gleitkommazahl: double;)
[sieh auch >
Umwandeln von Variablen]
| |
ListBox1.Items.Add(IntToStr(Zahl));
//Ganzzahl
ListBox1.Items.Add(FloatToStr(Gleitkommazahl));
//Gleitkommazahl |

Eintrag nur dann hinzufügen wenn dieser nicht vorhanden ist
(
var S:
String;)
| |
S := ('hinzufügen
wenn nicht bereits vorhanden');
if
ListBox1.Items.IndexOf(S) = -1
then
ListBox1.Items.Add(S); |

Löschen einer Zeile (Items)
| |
ListBox1.Items.Delete(0);
//löscht die erste Zeile |
Kompletten Inhalt löschen
| |
ListBox1.Items.Clear;
//löscht alle Zeilen |

Anzahl der Zeilen (Items)
ermitteln
| |
var
Zeilen: Integer;
Zeilen := ListBox1.Items.Count; |

Suchen nach Eintrag
| |
var
Zeile: Integer;
Zeile := ListBox1.Items.IndexOf('Suchwort')
// wird ‚Suchwort’ nicht als Eintrag (komplette Zeile) in
ListBox1 gefunden ist der Ausgabewert in Variable Zeile -1
// wird ‚Suchwort’ in ListBox1 gefunden, enthält die Variable
Zeile die erste Zeile in der ‚Suchwort’ gefunden wird
|

Einfügen einer Zeile nach der aktuell markierten
Zeile (Items)
Dieses
Beispiel fügt eine neue Zeile in eine ListBox ein. Die
Einfügposition ist die, der zuvor markierten Zeile. Die
Markierung wechselt zur eingefügten Zeile. Dabei wird zunächst
der gesamte Inhalt der ListBox in eine TStringList (Puffer)
geschaufelt, dann alle Einträge nach dem markierten Eintrag von
der ListBox gelöscht, die neue Zeile hinzugefügt und
anschließend die Einträge nach der Markierung angehangen. Dann
wird der Inhalt der ListBox gelöscht und mit dem Inhalt von der
TStringList wieder gefüllt.
| |
var
i, Pos: Integer;
Puffer: TStringList;
Puffer := TStringList.Create;
Pos := ListBox1.ItemIndex;
for i :=
1 to ListBox1.Items.Count
do
Puffer.Add(ListBox1.Items[i-1]);
for i :=
1 to Puffer.Count - Pos - 1
do
Puffer.Delete(Puffer.Count-1);
Puffer.Add('Das ist eine neue Zeile');
for
i := 1 to ListBox1.Items.Count
- Pos - 1
do
Puffer.Add(ListBox1.Items[Pos+i]);
ListBox1.Clear;
for i :=
1 to Puffer.Count
do
ListBox1.Items.Add(Puffer[i-1]);
ListBox1.ItemIndex := Pos + 1;
Puffer.Free; |

Doppelte Einträge löschen
| |
n :=
0;
while n <=
ListBox1.Items.count - 2
do
begin
for i :=
n + 1
to ListBox1.Items.count -
1
do
begin
if ListBox1.Items[n] =
ListBox1.Items[i] then
begin
dec(n);
ListBox1.Items.delete(i);
break;
end;
end;
inc(n);
end; |
|
// Quelle www.delphipraxis.net |

Inhalt aus Datei laden
| |
ListBox1.Items.LoadFromFile('Datei.txt');
// hier wäre es angebracht die Anweisung in ein "try except" zu
packen > sieh hier |
Inhalt in Datei speichern
| |
ListBox1.Items.SaveToFile('Datei.txt');
// hier wäre es angebracht die Anweisung in ein "try except" zu
packen > sieh hier
ListBox1.Items.SaveToFile('Datei.txt',
TEncoding.ASCII);
// in ASCII Zeichenkodierung
ListBox1.Items.SaveToFile('Datei.txt',
TEncoding.UTF8);
// in UTF8 Zeichenkodierung |

Kompletter Inhalt in eine TStringlist kopieren
und wieder zurück
| |
var
SList: TStringList;
SList := TStringList.Create;
//SList.Assign (ListBox1.Items);
// Inhalt wird gespiegelt, vorhandener Inhalt geht verloren
//SList.AddStrings(self.ListBox1.Items)
// Inhalt aus ComboBox wird hinzukopiert, vorhandener Inhalt
bleibt erhalten
// und wieder zurück
ComboBox1.Items
:= SList;
// Inhalt wird gespiegelt, vorhandener Inhalt geht verloren
SList.Free; |

Markierte (selektierte) Zeile (Items)
ermitteln
| |
var
Zeilen: Integer;
Zeilen := ListBox1.ItemIndex |

Markierung (Selektion) aufheben
| |
ListBox1.ItemIndex := -1; |

TPopupMenu einbinden
Zunächst eine TPopupMenu Komponente
auf die Form ziehen. Danach bei der entsprechenden ListBox im
Objektinspektor unter Ereignisse ins Feld PoupMenu klicken und
das entsprechende PopupMenu auswählen. Nun durch einen
Doppelklick auf die PopupMenu Komponente einen Eintrag
hinzufügen (Objektinsektor muss dazu auf Eigenschaften stehen
und der Cursor im Feld Caption stehen). Hinterlegt man
nun diesem Eintrag eine Procedure (siehe
TMainMenu) so kann in dieser die angewählte Zeile abfragen.
Das geht so:
| |
Edit1.Text :=
ListBox1.Items[ListBox1.ItemIndex]
// in Edit1 wird nun der Inhalt von der ausgewählten ListBox
Zeile ausgegeben |

Mit Rechtsklick markieren
Möchte man mit einem Rechtsklick, auch gleich die entsprechende ListBoxZeile markieren, dann hinterlegt man
folgende Programmzeilen, hinter dem Ereignis OnMouseDown (Objektinspektor ->
Ereignisse zur entsprechenden ListBox):
Bitte beachte,
dass die mit dem Hinweis versehene Zeile nur dann benötigt wird,
wenn auch ein PopUpMenue vorhanden ist, ansonsten verursacht
diese Zeile einen Zugriffsfehler.
| |
var
cursorpos : TPoint;
ndx : integer;
if Button=mbRight
then
begin
cursorpos.X := X;
cursorpos.Y := y;
ndx := ListBox1.ItemAtPos(cursorpos,true);
if (ndx <> -1)
then
begin
with (Sender
as
TListBox)
do
begin
Selected[ndx] := True;
cursorpos := ClientToScreen(cursorpos);
PopupMenu.Popup(cursorpos.x + Left,cursorpos.Y+10);
//<- nur wenn auch ein PopUpMenue vorhanden ist !!!
end;
end;
end; |

Drag & Drop
Um Einträge von
einer zur anderen ListBox per Drag & Drop zu kopieren, muss man
drei Schritte erledigen. Im folgenden Beispiel wird zunächst
davon ausgegangen dass man Einträge von ListBox1 zur ListBox2
kopieren möchte.
|
Schritt
1.) |
Bei
der sendenden ListBox (Quelle) muss im
Objektinspektor/Eigenschaften DragMode auf
dmAutomatic stehen |
|
Schritt 2.) |
Bei der empfangenden
ListBox (Ziel) im Objektinspektor/Ereignisse für
OnDragOver eine Procedure erstellen
(Doppelklick auf das leere Feld dahinter) und
folgenden Code schreiben:
Accept := True;
|
|
Schritt 3.) |
Bei
der empfangenden ListBox (Ziel) im
Objektinspektor/Ereignisse für OnDragDrop
eine Procedure erstellen (Doppelklick auf das leere Feld
dahinter) und folgenden Code schreiben:
(benötigt Variabelendeklaration:
var
Eintrag :
string;)
Eintrag :=
ListBox1.items[ListBox1.Itemindex];
// kopiert gezogenen Eintrag in die Variable Eintrag
ListBox2.Items.Add(Eintrag);
// fügt den Text in Variable Eintrag der Liste als neuen
Eintrag hinzu |
Im Großen und
Ganzen war's das schon, jedoch könnten folgende Ergänzungen noch
recht interessant sein.
Zu Schritt
2.)
mit
Accept :=
True; wird prinzipiell festgelegt, das die Quelle beliebiger
Herkunft sein darf, also auch von einer anderen ListBox als
ListBox2 oder gar einer Komponente. Um diese Freiheit
auszunutzen muss man allerdings unter Schritt 3
einen anderen Code hinterlegen aber dazu weiter unten mehr. Man
kann hier die Quelle aber auch schon einschränken. z.B. durch
verwenden von:
| |
if
Source is
TListBox
then Accept := True;
//
Hier wird festgelegt, dass die Quelle eine TListBox sein muss. |
Zu Schritt
3.)
Mit dem oben im
Beispiel gezeigtem Code ist die Quelle und das Ziel quasi
festgelegt. Möchte man jedoch die Quelle hier nicht festlegen,
um z.B. mehrere ListBox'en als mögliche Quelle zu nutzen, so
könnte der Code wie folgt aussehen:
| |
Eintrag := (Source
as
TListBox).Items[(Source
as
TListBox).ItemIndex]; |
Oder man möchte
z.B. ein TEdit als Ziel nutzen. Dann führt man die Schritte 1
und 2 an einer TEdit durch und unter Schritt 3 könnte die zweite
Zeile so aussehen:
| |
Edit1.Text := (Source
as
TListBox).Items[(Source
as
TListBox).ItemIndex] |

Verschieben von Items innerhalb einer ListBox
Verschieben mittels Drag&Drop:
Zunächst muss
man im Objektinspektor
den "dragMode" der betreffenden ListBox auf dmAutomatic
setzen. Dies ist quasi das Einschalten der Funktionalität
Drag&Drop. Damit nur Einträge innerhalb der ListBox akzeptiert
werden schreibt man hinter dem Ereignis OnDragOver
folgenden Code:
| |
if
Source <> ListBox1
then
Accept := FALSE |
Und zum
Schluss noch der Code für das eigentliche Verschieben, hinter
dem Ereignis OnDragDrop: (var
von, nach: Integer;)
| |
if
Source = ListBox1
then
begin
von := ListBox1.ItemIndex;
nach := ListBox1.ItemAtPos(Point(X, Y),
TRUE);
if nach = -1
then nach :=
ListBox1.Items.Count-1;
ListBox1.Items.Move(von, nach);
end; |
Verschieben mittels Up- und
Down-Button:
Wie bei der Drag&Drop-Methode muss auch hier die Eigenschaft "dragMode" auf dmAutomatic
gesetzt werden.
| |
// verschiebe Item in ListBox aufwärts
procedure
ListBoxItemUp(AListBox: TListBox);
var
CurrIndex: Integer;
begin
with AListBox
do
if ItemIndex >
0
then
begin
CurrIndex :=
ItemIndex;
Items.Move(ItemIndex, (CurrIndex - 1));
ItemIndex :=
CurrIndex - 1;
end;
end;
// verschiebe Item in ListBox abwärts
procedure
ListBoxItemDown(AListBox: TListBox);
var
CurrIndex, LastIndex: Integer;
begin
with AListBox
do
begin
CurrIndex := ItemIndex;
LastIndex := Items.Count;
if ItemIndex <> -1
then
begin
if CurrIndex +
1 < LastIndex
then
begin
Items.Move(ItemIndex, (CurrIndex + 1));
ItemIndex := CurrIndex + 1;
end;
end;
end;
end; |
Hinter den
gewünschten Buttons folgenden Code hinterlegen:
| |
ListBoxItemUp(ListBox1);
// noch oben verschieben
ListBoxItemDown(ListBox1);
// nach unten verschieben |

ListBox
mit einem BMP vor jedem Eintrag
Um die Optik
der sonst recht schlichten TListBox etwas aufzupeppen kann z.B.
vor jeden Eintrag ein BMP-Icon setzen. Und so geht's:Zunächst
sollten folgende beiden Einstellungen zur betreffenden ListBox
im Objektinspektor vorgenommen werden:
Style auf lbOwnerDrawFixed setzen
und bei ItemHeight die Pixelhöhe des BMP's
angeben, bzw. 2 Pixel mehr angeben...
Danach
folgenden Code in der entsprechenden Unit platzieren:
| |
procedure
DrawListBoxEx(Control: TWinControl; Index: Integer; Rect: TRect;
State: TOwnerDrawState);
const
Col2:
array [Boolean]
of TColor = (clInactiveCaptionText,
clWindowText);
var
Bmp: TBitmap;
TopDif: Integer; //
Gleicht die Höhendifferenz aus
begin
Bmp := TBitmap.Create;
try
with (Control as TListbox)
do
begin
Bmp.Transparent := True;
//
Hier Beispiel um Bitmap von Festplatte laden
Bmp.LoadFromFile('c:\DeinBild.bmp');
if odSelected
in State
then
Canvas.Font.Color := clCaptionText
else
Canvas.Font.Color := Col2[(Control as TListbox).Enabled];
// tauschen wenn farbige Items gewünscht,
siehe hier !
TopDif := (ItemHeight
div
2) - (Canvas.TextHeight(#32)
div
2);
Canvas.TextRect(Rect, Rect.Left
+ Bmp.Width + 1, Rect.Top + TopDif, Items[Index]);
Canvas.Draw(Rect.Left, Rect.Top,
Bmp);
end
finally
Bmp.Free;
end;
end; |
|
Quelle:
Delphi-Library.de |
Dann muss das Zeichnen der
Einträge noch angestoßen werden. Hier im Beispiel hinter dem
ListBox-Event OnDrawItem.
| |
DrawListBoxEx(Control, Index, Rect, State);
|

ListBox
mit farbigen Zeilen
Eine weitere
Möglichkeit um eine ListBox ein wenig aufzupeppen ist, das
Einfärben von einzelnen Zeilen. Dazu muss zunächst im
Objektinspektor das
Style auf lbOwnerDrawFixed setzen.
Beim Ereignis OnDrawItem
wird dann folgender Code hinterlegt:
| |
with Control as TListBox do
begin
Canvas.FillRect(Rect);
Canvas.Font.Color := TColor(Items.Objects[Index]);
Canvas.TextOut(Rect.Left +2, Rect.Top, Items[Index]);
end; |
Die einzelnen farbigen Items
werden dann wie folgt hinzugefügt:
| |
ListBox1.Items.AddObject('Ich
bin rot', Pointer(clRed));
ListBox1.Items.AddObject('Ich
bin blau', Pointer(clBlue)); |
Möchte man farbige
Einträge mit "BMP's
vor jedem Item" kombinieren, so wird die entsprechend
markierte Zeile im Quelltext gegen folgende Zeile getauscht:
| |
Canvas.Font.Color :=
TColor(Items.Objects[Index]); |

|