Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi ComboBox Einträge editieren (https://www.delphipraxis.net/152872-combobox-eintraege-editieren.html)

Chemiker 10. Jul 2010 11:36

ComboBox Einträge editieren
 
Hallo,

ich arbeite zurzeit mit einer ComboBox in der Einträge vorhanden sind und weitere im Programm hinzugefügt werden sollen, desweiteren sollen Einträge auch wieder gelöscht werden. Dafür wird das Event KeyDown benutzt.

Ein wenig Quelltext:

Delphi-Quellcode:
procedure TfrmMainDB_Eigenschaften.cBoxServernameKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
var i: integer;
begin
  if Key = VK_RETURN then
  begin
    if cBoxServername.ItemIndex= -1  then    // Kein Eintrag vorhanden
                                              // ohne Prüfung eintragen
    begin
      cBoxServername.Items.Add(cBoxServername.Text);
    end else
    begin
      for I := 0 to cBoxServername.Items.Count - 1 do
      begin
        // Doppelte und leere Einträge verhindern
        if not (cBoxServername.Items[i] =
          cBoxServername.Text) and not (Trim(cBoxServername.Text)= '') then
        begin
          if cBoxServername.Items.IndexOf(cBoxServername.Text) < 0 then
          begin
            cBoxServername.Items.Add(cBoxServername.Text);
          end;
        end;
      end;
    end;
    Key:= 0;
  end;
  if Key = VK_DELETE then
  begin
    for I := 0 to cBoxServername.Items.Count - 1 do
    begin
      if cBoxServername.Items[i] = cBoxServername.Text then
      begin
        cBoxServername.DeleteSelected; // Angezeiter Eintrage löschen
        cBoxServername.ItemIndex := 0; // Auf den ersten Eintrag einstellen
                                       // soweit vorhanden.
        key:= 0;
        break;
      end;
    end;
  end;
  if Key = VK_BACK then
  begin

    key:= 0;
  end;
end;
Bevor ich jetzt weiter mache ist meine Frage, gibt’s dafür eigentlich eine fertige Lösung die ich noch nicht gefunden habe, oder muss man es eben alles von Hand machen?

Bis bald Chemiker

DeddyH 10. Jul 2010 11:56

AW: ComboBox Einträge editieren
 
Sollte nicht in beiden Fällen eine Prüfung mit IndexOf ausreichen? Irgendwie sieht mir das so zu kompliziert aus.

[edit] Ich dachte mir das in etwa so:
Delphi-Quellcode:
procedure TForm1.cBoxServernameKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var idx: integer;
begin
  idx := cBoxServername.Items.IndexOf(cBoxServername.Text);
  case Key of
    VK_RETURN: begin
                 Key := 0;
                 if idx = -1 then
                   cBoxServername.Items.Add(cBoxServername.Text);
               end;
    VK_DELETE: begin
                 if idx > -1 then
                   begin
                     cBoxServername.Items.Delete(idx);
                     if cBoxServername.Items.Count > 0 then
                       cBoxServername.ItemIndex := 0;
                   end;
                 Key := 0;
               end;
  end;
end;
[/edit]
[edit2] Den Signalton bekommst Du übrigens im OnKeyDown nicht weg, das musst Du schon im OnKeyPress machen. [/edit2]

Chemiker 11. Jul 2010 14:09

AW: ComboBox Einträge editieren
 
Hallo DaddyH,

hatte den Quellcode erst grade gesehen. Hatte heute Morgen das Event nach Deiner Empfehlung von gestern noch mal Überarbeitet. Abweichend zu Deiner Lösung werden keine Leerzeichen in die String-Liste übernommen und man kann auch den letzten Eintrag löschen. Habe zusätzlich AutoComplete auf FLASE gesetzt, damit können die vorhanden Einträge besser bearbeitet werden.

Delphi-Quellcode:
procedure TfrmMainDB_Eigenschaften.cBoxServernameKeyDown(Sender: TObject;
  var Key: Word; Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    // Leer Zeichen nicht in die Liste übernehmen.
    if ((cBoxServername.Items.IndexOf(cBoxServername.Text) = -1) and
      (not (Trim(cBoxServername.Text) = ''))) then
    begin
      cBoxServername.Items.Add(cBoxServername.Text);
    end;
  end;
  if Key = VK_DELETE then
  begin
    if cBoxServername.Items.IndexOf(cBoxServername.Text) > -1 then
    begin
      cBoxServername.Items.Delete(cBoxServername.Items.IndexOf(cBoxServername.Text));
      if cBoxServername.Items.Count > -1 then
      begin
        cBoxServername.ItemIndex := 0; // Auf den ersten Eintrag einstellen
                                       // soweit vorhanden.
      end;
    end;
  end;
  Key:= 0;
end;
Vielen Dank für Deine Hilfe.

Bis bald Chemiker

DeddyH 11. Jul 2010 16:58

AW: ComboBox Einträge editieren
 
Den letzten Eintrag kannst Du bei mir auch löschen, nur kannst Du den ItemIndex nicht setzen, wenn gar keine Items vorhanden sind ;)

xZise 11. Jul 2010 17:33

AW: ComboBox Einträge editieren
 
Ich würde auch nicht öfters IndexOf() aufrufen ;) Ich meine O(2n) liegt zwar auch in O(n), aber es halbiert i.A. die Laufzeit ;)

MfG
Fabian

Chemiker 11. Jul 2010 23:05

AW: ComboBox Einträge editieren
 
Hallo,

Zitat:

Zitat von DeddyH
Den letzten Eintrag kannst Du bei mir auch löschen, nur kannst Du den ItemIndex nicht setzen, wenn gar keine Items vorhanden sind

Es gelingt mir nicht den Eintrag zu löschen.

[Edit]
Delphi-Quellcode:
if cBoxServername.Items.Count > 0 then
es müssen min. 2 Einträge vorhanden sein, damit die Bedingung zutrifft.
[/Edit]


Zitat:

Zitat von xZise
Ich würde auch nicht öfters IndexOf() aufrufen Ich meine O(2n) liegt zwar auch in O(n), aber es halbiert i.A. die Laufzeit

Ich glaube nicht das die Ausführungszeit bei einer manuellen Eingabe so relevant ist, zu dem wird wenn nicht Enter oder Entfernen gedrückt wird Zeit eingespart weil IndexOf erst gar nicht aufgerufen wird.

Bis bald Chemiker

DeddyH 12. Jul 2010 09:47

AW: ComboBox Einträge editieren
 
Zitat:

Zitat von Chemiker (Beitrag 1034877)
[Edit]
Delphi-Quellcode:
if cBoxServername.Items.Count > 0 then
es müssen min. 2 Einträge vorhanden sein, damit die Bedingung zutrifft.
[/Edit

Das wäre mir aber neu. Count gibt die Anzahl der Elemente zurück, d.h. ein Count > 0 heißt mindestens ein Element vorhanden.

[edit] OK, hier noch einmal eine überarbeitete Version:
Delphi-Quellcode:
procedure TForm1.cBoxServernameKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
var idx: integer;
begin
  //Index einmalig ermitteln
  idx := cBoxServername.Items.IndexOf(cBoxServername.Text);
  //case statt if -> IMHO übersichtlicher und schneller
  case Key of
    VK_RETURN: begin
                 //wenn Text nicht vorhanden und
                 //nicht nur aus Leer- bzw. Steuerzeichen bestehend -> eintragen
                 if (idx = -1) and (trim(cBoxServername.Text) <> '') then
                   cBoxServername.Items.Add(cBoxServername.Text);
               end;
    VK_DELETE: begin
                 //wenn Eintrag gefunden
                 if idx > -1 then
                   begin
                     //Eintrag löschen
                     cBoxServername.Items.Delete(idx);
                     //Erst einmal den alten Text löschen
                     cBoxServername.Text := '';
                     //-> wird ggf. durch geänderten Index neu gesetzt
                     if cBoxServername.Items.Count > 0 then
                       cBoxServername.ItemIndex := 0;
                     //notwendig, da Anzeige sonst nicht aktualisiert wird
                     Key := 0;
                   end;
               end;
  end;
end;

procedure TForm1.cBoxServernameKeyPress(Sender: TObject; var Key: Char);
begin
  //"Bimmeln" unterbinden
  if Key = sLineBreak[1] then
    Key := #0;
end;
[/edit]

Chemiker 12. Jul 2010 18:41

AW: ComboBox Einträge editieren
 
Hallo DeddyH,

Zitat:

Zitat von DeddyH
Das wäre mir aber neu. Count gibt die Anzahl der Elemente zurück, d.h. ein Count > 0 heißt mindestens ein Element vorhanden.

Nochmal zur Klärung:

Count = 0 erster Eintrag
Count = 1 zweiter Eintrag

Wenn Count > 0 // sollte Count mindestens 1 sein um die Bedienung zu erfüllen, oder?

Bis bald Chemiker

jfheins 12. Jul 2010 19:27

AW: ComboBox Einträge editieren
 
Zitat:

Zitat von Chemiker (Beitrag 1034987)
Hallo DeddyH,

Zitat:

Zitat von DeddyH
Das wäre mir aber neu. Count gibt die Anzahl der Elemente zurück, d.h. ein Count > 0 heißt mindestens ein Element vorhanden.

Nochmal zur Klärung:

Count = 0 erster Eintrag
Count = 1 zweiter Eintrag

Wenn Count > 0 // sollte Count mindestens 1 sein um die Bedienung zu erfüllen, oder?

Bis bald Chemiker

Denke nochmal über den Unterschied zwischen Count und Index nach. Count ist die Anzahl der Elemente. Wenn es ein Element gibt, hat das meistens den Index 0.

fatalerror 12. Jul 2010 19:38

AW: ComboBox Einträge editieren
 
Zitat:

Zitat von Chemiker (Beitrag 1034987)
Hallo DeddyH,

Zitat:

Zitat von DeddyH
Das wäre mir aber neu. Count gibt die Anzahl der Elemente zurück, d.h. ein Count > 0 heißt mindestens ein Element vorhanden.

Nochmal zur Klärung:

Count = 0 erster Eintrag
Count = 1 zweiter Eintrag

Wenn Count > 0 // sollte Count mindestens 1 sein um die Bedienung zu erfüllen, oder?

Bis bald Chemiker

Ich hoffe du verstehst selbst, dass deine Aussage nicht korrekt sein kann. Count heisst "zähle" Wenn es keinen Eintrag in der Liste hat, dann ergibt count auch 0.

Zum besseren Verständnis:

Delphi-Quellcode:

//Kein Eintrag in der Liste
combobox1.Items.Clear;
showmessage(inttostr(combobox1.Items.Count));


//4 Einträge zur Liste hinzufügen
for i:= 0 to 3 do
  combobox1.items.add('test-'+inttostr(i));

showmessage(inttostr(combobox1.Items.Count));

DeddyH 12. Jul 2010 19:42

AW: ComboBox Einträge editieren
 
Probier doch einfach meine überarbeitete Version aus und beobachte die Werte im Debugger ;)

Chemiker 12. Jul 2010 21:59

AW: ComboBox Einträge editieren
 
Hallo,

ja, ich gebe zu ich habe Count und Index gleichgesetzt, ohne zu prüfen ob meine Aussage richtig ist.

Im ersten Quellcode von DeddyH schien es so, als wenn der letzte Eintrag nicht gelöscht worden wäre. Dies ist aber nicht richtig, sondern es ist nur der ComboBox.Text stehen geblieben.

Bis bald Chemiker

Chemiker 17. Jul 2010 10:42

AW: ComboBox Einträge editieren
 
Hallo,

nochmal eine Frage. Das neue Item wird erst mit ENTER übernommen, wenn zuvor die ComboBox mit der Maus aufgeklappt worden ist, trotzdem im OI AutoDropDown := TRUE ist. Wie kann man das Verhalten ändern, so dass die Eingabe direkt nach ENTER drücken übernommen wird?

Bis bald Chemiker

DeddyH 17. Jul 2010 11:04

AW: ComboBox Einträge editieren
 
Zitat:

Zitat von Chemiker (Beitrag 1035811)
Das neue Item wird erst mit ENTER übernommen, wenn zuvor die ComboBox mit der Maus aufgeklappt worden ist, ...

Das kann ich hier nicht nachvollziehen. Wie ist die ComboBox denn genau eingestellt (OI)?

Chemiker 17. Jul 2010 11:29

AW: ComboBox Einträge editieren
 
Hallo DeddyH,
So sind zurzeit die Einstellungen:
Delphi-Quellcode:
object cBoxServername: TComboBox
      Left = 127
      Top = 36
      Width = 145
      Height = 22
      AutoComplete = False
      AutoDropDown = True
      ItemHeight = 14
      ItemIndex = 0
      TabOrder = 1
      Text = 'localhost'
      OnKeyDown = cBoxServernameKeyDown
      OnKeyPress = cBoxServernameKeyPress
      Items.Strings = (
        'localhost')
    end
Bis bald Chemiker

sx2008 17. Jul 2010 12:50

AW: ComboBox Einträge editieren
 
Zitat:

Zitat von Chemiker (Beitrag 1034638)
ich arbeite zurzeit mit einer ComboBox in der Einträge vorhanden sind und weitere im Programm hinzugefügt werden sollen, desweiteren sollen Einträge auch wieder gelöscht werden.

Vielleicht sollte man erst mal das genaue Verhalten der Combobox klären, bevor man (wild) drauflos programmiert.

Ein Beispiel:
Der Benutzer gibt eine URL ein, um sich die Daten anzeigen zu lassen.
Wird die URL gefunden dann wird sie in die Drop-Down-Liste aufgenommen.
Das Programm steuert den Zeitpunkt der Aufnahme des eingegeben Text in die Liste durch Aufruf einer Methode.
So wird verhindert, dass ungültige URLs in die Liste aufgenommen werden.
Einträge sollen nicht doppelt aufgenommen werden.
Da nur eine begrenzte Anzahl in der Drop-Down-Liste sein soll, verdrängt der neueste Einträg den Ältesten.
Wenn die Drop-Down-Liste aufgeklappt ist, darf der Benutzer mit der DEL-Taste Einträge löschen.
Er darf Einträge in der Liste nicht direkt editieren.
Die Einträge in der Liste können entweder in der Reihenfolge ihrer Aufnahme oder alphabetisch sortiert sein.


Erst wenn es eine Beschreibung dieser Art (User story) gibt, dann kann man auch was Sinnvolles Programmieren!

hans ditter 17. Jul 2010 13:25

AW: ComboBox Einträge editieren
 
Zitat:

Zitat von DeddyH (Beitrag 1034910)
[Edit]
Delphi-Quellcode:
procedure TForm1.cBoxServernameKeyPress(Sender: TObject; var Key: Char);
begin
  //"Bimmeln" unterbinden
  if Key = sLineBreak[1] then
    Key := #0;
end;
[/edit]

Hallo DaddyH. Ich hätte mal eine Frage. Wie funktioniert
Delphi-Quellcode:
sLineBreak[1]
und vor allem: Wie willst du damit das "Bimmeln" unterdrücken? Wär super wenn du das kurz umreissen könntest, weil mich das auch schon ewig nervt bei OnKeyDown:mrgreen:

DeddyH 17. Jul 2010 14:02

AW: ComboBox Einträge editieren
 
Hallo Hans,

die Konstante sLineBreak ist unter Windows als #13#10 (CRLF) definiert, ich hätte also auch gleich #13 schreiben können. Da einige damit aber immer wieder durcheinanderkommen, habe ich mich entschieden, das so zu schreiben, dass jeder weiß, dass damit das erste Zeichen der Konstanten gemeint ist. Und da Windows nunmal einen Ton ausgibt, wenn man im Eingabefeld einer ComboBox RETURN drückt, muss man das Zeichen eben entwerten, indem man ihm den Wert 0 zuweist (es ist ja nicht ohne Grund ein Var-Parameter). Im OnKeyDown-Ereignis kommt das RETURN trotzdem an.

Chemiker 17. Jul 2010 14:10

AW: ComboBox Einträge editieren
 
Hallo sx2008,

danke für Deine Ausführungen, aber ich habe sehr wohl eine Vorstellung wie diese ComboBox aussehen soll und wie sie zu bedienen ist. Außerdem wird im zarten Alter von 50 Jahren nicht mehr wild drauflos programmiert das geht rein körperlich schon nicht mehr.

Ich habe den Fehler jetzt nach einigen probieren gefunden. Wenn man eine TBitBtn-Komponente auf das Form zieht und das Kind-Property auf bkOK setzt, dann funktioniert die Eingabe in der ComboBox erst, wenn sie aufgeklappt ist. Warum das so ist bin ich noch am untersuchen.

Bis bald Chemiker

DeddyH 17. Jul 2010 14:19

AW: ComboBox Einträge editieren
 
Dann weiß ich auch, wieso der Fehler bei mir nicht aufgetreten ist :zwinker:

[edit] Aus der Hilfe zu TBitBtnKind:
Zitat:

bkOK
Auf der Schaltfläche wird der Text "OK" (eventuell mit einem grünen Häkchen) angezeigt. Die Schaltfläche wird zur Standardschaltfläche (die Eigenschaft Default wird automatisch auf true gesetzt). Wenn der Benutzer auf die Schaltfläche klickt, wird das Dialogfeld geschlossen. Der ModalResult-Wert dieser Schaltfläche ist mrOK.
Da hamwas.[/edit]

Chemiker 17. Jul 2010 17:31

AW: ComboBox Einträge editieren
 
Hallo DeddyH,

habe einfach Default von BitBtn1 auf FALSE zurückgestellt, dann wird zwar Kind auf bkCustom zurückgestellt, aber die Bitmap bleibt auf OK mit einem Häkchen.

Hast Du vorher gewusst, dass der Default-Wert auf True umgestellt wird?

Bis bald Chemiker

xZise 17. Jul 2010 18:49

AW: ComboBox Einträge editieren
 
Es ist anzunehmen. Außerdem wird der Default Button in der IDE hervorgehoben.

MfG
Fabian

DeddyH 17. Jul 2010 22:31

AW: ComboBox Einträge editieren
 
Ich habe es vorher nicht gewusst, aber nach dem Hinweis auf den BitBtn in der Hilfe nachgelesen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:41 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