![]() |
Editfeld mit Dropdownmenü
Hallo,
nachdem ich jetzt eine Idee bekommen habe wie ich mit .ini-Dateien umgehe, steht das nächste Problem an. Und zwar habe ich vor, dass bei einem Editfeld ein Dropdown menü erscheint. Dabei sollen in dem Dropdownmenü Vorschläge aus einer Liste der Ini-Datei (einer Section) angeboten werden. Wie beim normalen Autovervollständigen sollen dann auch immer nur die Vorschläge angezeigt werden, die durch die schon eingegebenen Buchstaben nicht ausgeschlossen sind. Ich habe eine solche Komponente nicht finden können :-/. Bzw. Ich weis nicht wie sie heißt. Vielen Dank schonmal im vorraus. Kahpee |
Re: Editfeld mit Dropdownmenü
|
Re: Editfeld mit Dropdownmenü
Das es nicht nur bei der Idee bleibt
![]() |
Re: Editfeld mit Dropdownmenü
Und dann noch dem OnChange-Event der Combobox das hier zuweisen.
Delphi-Quellcode:
procedure TForm13.ComboBox1Change(Sender: TObject);
var selstart, sellength, i: Integer; edCombobox : TComboBox; begin edComboBox := Sender as TComboBox; selstart := edComboBox.SelStart; sellength := edComboBox.SelLength; edCombobox.Items.BeginUpdate; try edCombobox.Items.Clear; for i := 0 to Memo1.Lines.Count - 1 do if (edComboBox.Text = '') or (Pos(edComboBox.Text, StringList_Vorschlaege[i]) = 1) then edComboBox.Items.Add(memo1.Lines[i]); finally edComboBox.items.endUpdate; end; edComboBox.SelStart := selstart; edComboBox.SelLength := sellength; end; |
Re: Editfeld mit Dropdownmenü
Hallo,
vielen Dank schon mal für die Antworten. Was genau soll Memo1 sein? Ich habe bei mir gar kein Memo! Kann ich die Liste auch irgendwie anders einlesen? Was genau bedeutet "Pos" an dieser Stelle?:
Delphi-Quellcode:
Der ganze Befehl/Vergleich ist mir unklar und ich hab das gefühl, dass genau der entscheident ist ;)
Pos(edComboBox.Text, StringList_Vorschlaege[i])
Warum die variablen Selstart und Sellength? Die Variable wird doch nie verändert. Oder doch? Die Liste der Vorschläge ist in einer Ini in folgender Form:
Delphi-Quellcode:
[Liste]
anzahleinträge=5 1=Albert 2=Heinz 3=Ludwig 4=Mathilda 5=Hartmund Wie muss das dann aussehen? Muss ich die Liste erstmal auslesen uns zwischenspeichern? Ich hab schon mal die "Sorte"-Option aktiviert damit das ganze in alphabetischer Reihenfolge angezeigt wird. Vielen Dank schon mal im voraus für weitere Hilfestellungen Kahpee |
Re: Editfeld mit Dropdownmenü
Hallo,
ich kann dir die ![]() ![]() ![]() ![]() Pos prüft, ob ein String in einem anderen enthalten ist bzw. gibt den Index zurück. SeltStart und SelLength sind keine Variablen in dem Sinne. Hier wird festgelegt, von wo bis wo ein Text markiert werden soll. Aber das steht alles in der Delphi-Reference bzw. in der Delphi-Hilfe. Deine ini-Inhalte musst du in die ComboBox einlesen. Das von alzaimar erwähnte TMemo ist nur ein Beispiel. Statt des Memos musst du eben die Inhalte der Ini-Datei auslesen und der ComboBox hinzufügen (eine kleine For-Schleife reicht hier aus). |
Re: Editfeld mit Dropdownmenü
In die Combobox sollte das doch nicht eingelesen werde oder? Weil die Liste wird ja zwischen drin immer gecleart.. Gibt es denn eine Variable die ich benutzen könnte? (Typ Tstring?) Oder muss ich das mit einem unsichtbaren Memo oder einer unsichtbaren Listbox realisieren?
KahPee |
Re: Editfeld mit Dropdownmenü
Aus dem Kopf getippselt und ungetestet irgendwie sowas:
Delphi-Quellcode:
Um nicht laufend auf die Ini-Datei zugreifen zu müssen, kannst du diese einmalig in eine TStringList einlesen und daraus dann die ComboBox füllen.
var
i: Integer; EntryNum: Integer; EntryValue: string; MyIni := TIniFile.Create(...); try // read number of entries EntryNum := MyIni.ReadInteger('Liste', 'anzahleinträge', 0); MyComboBox.Items.Clear; MyComboBox.Items.BeginUpdate; // add items for i := 1 to EntryNum do begin EntryValue := MyIni.ReadString('Liste', IntToStr(i), ''); if ((EntryValue != '') and (Pos(EntryValue, MyEdit.Text) > 0)) then MyComboBox.Items.Add(EntryValue); end; MyComboBox.Items.EndUpdate; finally FreeAndNil(MyIni); end; Das Prinzip ist dabei das gleiche: Die StringList in einer Schleife durchgehen, Werte prüfen und ggf. hinzufügen. |
Re: Editfeld mit Dropdownmenü
Delphi-Quellcode:
Und die existierende ini dazu:
procedure Tform2.Autocomplete(Combobox: TCombobox);
var selstart, sellength,i: Integer; EntryNum: Integer; EntryValue: string; statistic: TiniFile; begin statistic:= TIniFile.Create(ExtractFilePath(ParamStr(0))+'statistic.ini'); try // read number of entries EntryNum := statistic.ReadInteger('Playerlist', 'count', 0); selstart := Combobox.SelStart; sellength := Combobox.SelLength; Combobox.Items.Clear; Combobox.Items.BeginUpdate; // add items for i := 1 to EntryNum do begin EntryValue := statistic.ReadString('Playerlist', IntToStr(i), ''); if ((EntryValue = '') or (Pos(EntryValue, Combobox.Text) > 0)) then begin Combobox.Items.Add(EntryValue); end; end; Combobox.Items.EndUpdate; finally statistic.Free; Combobox.SelStart := selstart; Combobox.SelLength := sellength; showmessage(inttostr(entrynum)+entryvalue); // gibt immer "3Bert" aus end; end;
Delphi-Quellcode:
eingebunden durch:
[Playerlist]
count=3 1=Hartmund 2=Albert 3=Bert
Delphi-Quellcode:
So das hab ich draus gemacht. Aber im Moment wird eine leeres Dropdownmenü angezeigt, ohne einen einzigen Eintrag. Außerdem wird der Eintrag den man eintippt immer gleich gelöscht, nach durchlauf der prozedur. Die Datei heißt auch wirklich "statistic.ini" und liegt im selben Ordner wie die .exe .
procedure TForm2.CBplayer1Change(Sender: TObject);
begin Autocomplete(sender as Tcombobox); end; mfg Kahpee |
Re: Editfeld mit Dropdownmenü
Delphi-Quellcode:
Das bedeutet, wenn EntryValue leer ist ODER einen Teilstring enthält, wird EntryValue in die ComboBox eingefügt. Wieso sollte ein Leerstring in die ComboBox eingefügt werden? Das passiert somit auch bei jedem Versuch, aus der ini zu lesen, der fehlschlägt, da der Standardwert ein Leerstring ist.
if ((EntryValue = '') or (Pos(EntryValue, Combobox.Text) > 0)) then
Es ist imho auch Quatsch, in Pos() den Inhalt der ComboBox zu vergleichen. Denn diese leerst du und füllst sie anschließend. Du musst natürlich mit deinem Suchbegriff (Edit.Text) vergleichen. Lasse dir mal EntryValue ausgeben. Zugegeben, ich habe "!=" im Code geschrieben. In Delphi heißt es "<>", also:
Delphi-Quellcode:
Oder hier:
if ((EntryValue <> '') and (Pos(EntryValue, MyEdit.Text) > 0)) then
Delphi-Quellcode:
Natürlich gibt das immer "3Bert" aus, da du die Ausgabe nach Ablauf der Schleife machst. Damit wird immer der letzte Wert ausgegeben. Wenn du das innerhalb der Schleife aufrufst, sieht das schon anders aus.
showmessage(inttostr(entrynum)+entryvalue); // gibt immer "3Bert" aus
|
Re: Editfeld mit Dropdownmenü
Delphi-Quellcode:
So habe ich das in meinem Quelltext. Das oben war die falsche Kopie bei einigen rumspielereien.
if ((EntryValue <> '') and (Pos(EntryValue,Combobox.Text) > 0)) then
in Combobox.text (dem Text den jemand in die Combobox eingibt) steht der Suchbegriff. Das soll dann verglichen werden mit den Einträgen, die in der Inidatei zu finden sind. Die Einträge der Ini-datei, die noch passen würden (unter Berücksichtigung der eingegebenen Buchstaben) sollen dann im DropDownmenü angezeigt werden. Es soll durch aus möglich sein einen noch nicht in der Liste vorhandenen String (hier namen) einzugeben. Das Problem, das Combobox.text immer geleert wird besteht also weiterhin. Warum? Und warum zeigt er mir nicht als möglichen Eintrag am Anfang alle 3 Optionen und wenn ich z.B. "A" tippe "Albert" an? In der Schleife gibt mir showmessage (war nur zu kontrollzwecken eingebaut) folgendes aus: 3Albert 3Hartmund 3Bert Genau das ist ja eigentlich auch zu erwarten. Vielen Dank schon für die Hilfe. Ich hoffe wir finden das Problem noch ;) mfg KahPee |
Re: Editfeld mit Dropdownmenü
Wir haben die Parameter bei Pos() vertauscht. So funktioniert's bei mir (soeben getestet):
Delphi-Quellcode:
Grüße, Matze
procedure TForm1.Autocomplete(Combobox: TComboBox);
var EntryNum: Integer; EntryValue: string; statistic: TiniFile; i: Integer; begin statistic := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'statistic.ini'); try // read number of entries EntryNum := statistic.ReadInteger('Playerlist', 'count', 0); Combobox.Items.Clear; Combobox.Items.BeginUpdate; // add items for i := 1 to EntryNum do begin EntryValue := statistic.ReadString('Playerlist', IntToStr(i), ''); if ((EntryValue <> '') and (Pos(LowerCase(Combobox.Text), LowerCase(EntryValue)) = 1)) then begin Combobox.Items.Add(EntryValue); end; end; Combobox.Items.EndUpdate; finally FreeAndNil(statistic); end; end; |
Re: Editfeld mit Dropdownmenü
Das ist schon deutlich besser. Aber:
Im Moment setzt der Cursor immer wieder vor dem ersten Buchstaben an. Das ist natürlich murks. Ich möchte ja das man immer noch einen Namen eingeben kann als wenn es ein normales Editfeld wäre. |
Re: Editfeld mit Dropdownmenü
Dann frickel SelStart und SelLength wieder hinein. Beispielsweise so:
Delphi-Quellcode:
Ggf. sind noch Anpassungen notwendig.
procedure TForm1.Autocomplete(Combobox: TComboBox);
var EntryNum: Integer; EntryValue: string; statistic: TiniFile; i: Integer; InputLen: integer; begin statistic := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'statistic.ini'); try // read number of entries EntryNum := statistic.ReadInteger('Playerlist', 'count', 0); InputLen := Length(ComboBox.Text); Combobox.Items.Clear; Combobox.Items.BeginUpdate; // add items for i := 1 to EntryNum do begin EntryValue := statistic.ReadString('Playerlist', IntToStr(i), ''); if ((EntryValue <> '') and (Pos(LowerCase(Combobox.Text), LowerCase(EntryValue)) = 1)) then begin Combobox.Items.Add(EntryValue); end; end; Combobox.Items.EndUpdate; // get text of the first match if Combobox.Items.Count > 0 then begin ComboBox1.ItemIndex := 0; ComboBox1.SelStart := InputLen; ComboBox1.SelLength := Length(ComboBox.Text) - InputLen; end; finally FreeAndNil(statistic); end; end; |
Re: Editfeld mit Dropdownmenü
Super! Auch schön, das der Rest eines Wortes "selected" angezeigt wird. Allerdings gibt es jetzt noch ein klitzekleines Problem.
Wenn man A tippt kommt "albert" (dabei ist "lbert" selected). Wenn man dann l tippt kommt "albert" (dann ist nichts mehr selected) das ist doof! Wenn ich jetzt zum Beispiel Alejandro schreiben will ;) Das muss also auch beim zweiten Vorschlag selected sein! |
Re: Editfeld mit Dropdownmenü
Ich muss nun leider weg. Probiere doch selbst auch mal etwas und lasse dir nicht alles vorkauen.
Wenn du den Code wirklich verstanden hast, dann vermute ich, ist das problemlos machbar. Ich tippe darauf, dass es mit der Groß-/Kleinschreibung zusammenhängt, denn bei der Eingabe von "A" passt glaub alles. |
Re: Editfeld mit Dropdownmenü
Bis auf den Tippfehler 'memo1' (sollte 'StringList_Vorschlaege' heißen) funktioniert mein Code doch. Inklusive der Tatsache, das der Cursor dort bleibt, wo er ist. Beim letzten Vorschlag wird der Cursor strikt ans Ende des Inputstrings gesetzt, auch wenn er dort vorher gar nicht war.
|
Re: Editfeld mit Dropdownmenü
Delphi-Quellcode:
Damit klappts ;)
procedure Tform2.Autocomplete(Combobox: TCombobox);
var EntryNum, selstart, sellength: Integer; EntryValue: string; statistic: TiniFile; i: Integer; begin statistic := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'statistic.ini'); try EntryNum := statistic.ReadInteger('Playerlist', 'count', 0); selstart := ComboBox.SelStart; sellength := ComboBox.SelLength; Combobox.Items.Clear; Combobox.Items.BeginUpdate; for i := 1 to EntryNum do begin EntryValue := statistic.ReadString('Playerlist', IntToStr(i), ''); if (combobox.Text='') or((EntryValue <> '') and (Pos(LowerCase(Combobox.Text), LowerCase(EntryValue)) = 1)) then begin Combobox.Items.Add(EntryValue); end; end; Combobox.Items.EndUpdate; ComboBox.SelStart := selstart; ComboBox.SelLength := sellength; finally FreeAndNil(statistic); end; end; Vielen Dank |
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:08 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz