ComboBox doppelte Einträge

Rund um die LCL und andere Komponenten
Antworten
Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

ComboBox doppelte Einträge

Beitrag von Mathias »

Bei TStringList gibt es

Code: Alles auswählen

sl.Duplicates := dupIgnore;  

Gibt es so was auch direkt für die ComboBox.Items ?

Oder muss ich den Umweg über eine temporäre StringList machen, um die Doppelten Einträge zu entfernen ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: ComboBox doppelte Einträge

Beitrag von wp_xyz »

Code: Alles auswählen

constructor TCustomComboBox.Create(TheOwner : TComponent);
begin
  inherited Create(TheOwner);
  ...
  FItems := TStringlist.Create;     
  ...

Im Constructor von TCustomCombobox sieht man, dass die Items der Combobox als TStringlist erzeugt werden. Sie sind zwar nur als TStrings veröffentlicht, aber mit einem Typecast auf TStringlist müssten die Properties von TStringlist zugänglich werden:

Code: Alles auswählen

 TStringList(Combobox1.Items).AllowDuplicate := dupIgnore;

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ComboBox doppelte Einträge

Beitrag von Mathias »

Mit folgenden einfachen Code funktioniert es nicht, das "123" kommt genau so viel mal, wie ich auf den Button klicke.
Auch wen ich den ausgeklammerten Sort nehme geht es nicht.

Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
begin
  //  ComboBox1.Sorted := True;
  TStringList(ComboBox1.Items).Sorted := True;
  TStringList(ComboBox1.Items).Duplicates := dupIgnore;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
begin
  ComboBox1.Items.Add('123');
end;


Wie kommst du auf AllowDuplicate, dies wird vom Kompiler gar nicht erkannt ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: ComboBox doppelte Einträge

Beitrag von Michl »

Das mit dem Casten auf ein TStringList ist gefährlich, da die LCL Controls nativ sind. Zum Erstellen des Controls wird eine Dummy-TStringList verwendet. Wurde das Handle erstellt, wird ab dann z.B. unter Windows eine TWin32ListStringList bzw. TWin32ComboBoxStringList (direkte Nachfahren von TStrings) verwendet.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
begin
  TWin32ComboBoxStringList(ComboBox1.Items).Sorted := True// dieser Cast geht
  TStringList(ComboBox1.Items).Duplicates := dupIgnore;      // dieser geht nicht
  ComboBox1.Items.Add('123');
end;   
Zuletzt geändert von Michl am Do 7. Sep 2017, 20:28, insgesamt 1-mal geändert.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: ComboBox doppelte Einträge

Beitrag von theo »

Dann mach halt so:

Code: Alles auswählen

  if ComboBox1.Items.IndexOf('123') < 0 then ComboBox1.Items.Add('123')

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ComboBox doppelte Einträge

Beitrag von Mathias »

Danke, dies ist eine elegante Lösung.

Mein Ziel ist, eine ComboBox, die ähnlich funktioniert, wie der Menupunkt "Wieder öffnen...".

Code: Alles auswählen

procedure TForm1.Button7Click(Sender: TObject);
var
  sdd: TSelectDirectoryDialog;
  ini: TIniFile;
  i: integer;
  sl: TStringList;
const
  INIKey='tut_pfad';
begin
  ComboBox1.Clear;
  ini := TIniFile.Create(ConfigINIDatei);
 
  sl := TStringList.Create;
  ini.ReadSection(INIKey, sl);
  for i := 0 to sl.Count - 1 do begin
    ComboBox1.Items.Add(ini.ReadString(INIKey, sl[i], ''));
  end;
  sl.Free;
 
  sdd := TSelectDirectoryDialog.Create(Self);
  if sdd.Execute then begin
    i:=ComboBox1.Items.IndexOf(sdd.FileName);
    if i >= 0 then begin
      ComboBox1.Items.Delete(i);
    end;
    ComboBox1.Items.Insert(0, sdd.FileName);
    ComboBox1.ItemIndex := ComboBox1.Items.IndexOf(sdd.FileName);
  end;
  sdd.Free;
 
  for i := 0 to ComboBox1.Items.Count - 1 do begin
    ini.WriteString(INIKey, IntToStr(i), ComboBox1.Items[i]);
  end;
 
  ini.Free;
end;   
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: ComboBox doppelte Einträge

Beitrag von Mathias »

Ich habe die Funktion ein wenig modifiziert, somit wird bei einem Duplikat, dies wieder auf die oberste Position gesetzt.

Code: Alles auswählen

procedure TSerial_Monitor_Form.Button_SendClick(Sender: TObject);
var
  i: integer;
  s: string;
begin
  s := ComboBox_Send_Text.Text;
  if Length(s) > 0 then begin
    SerWrite(SerialHandle, s[1], Length(s));

    i := ComboBox_Send_Text.Items.IndexOf(s);
    if i >= 0 then begin
      ComboBox_Send_Text.Items.Delete(i);
    end;

    ComboBox_Send_Text.Items.Insert(0, s);
    ComboBox_Send_Text.Text := s;
  end;
end; 
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten