Delphi

Tre modi per riempire una ComboBox senza ripetere codice

calendar_today personTeam EGSOFT schedule4 min di lettura
info

Disclaimer: le informazioni pubblicate in questa sezione hanno finalità di pura divulgazione tecnica. EG Software S.r.l. non si assume alcuna responsabilità per un utilizzo improprio dei contenuti, né per eventuali danni diretti o indiretti derivanti dalla loro applicazione, e non garantisce l'aggiornamento, l'accuratezza o la completezza delle informazioni riportate. Prima di utilizzare in produzione codice o procedure qui descritte, verificane sempre l'adeguatezza al proprio contesto.

Popolare una TComboBox è un'operazione banale finché non la si ritrova copiata e incollata in dieci form diversi, ognuno con una sorgente dati differente: un array statico, un file di configurazione JSON, il risultato di una query. Incapsulare questa logica in piccole classi dedicate riduce la duplicazione e rende più semplice cambiare sorgente in futuro senza toccare il codice del form.

Da un array o da un JSON

La stessa classe può esporre due metodi distinti per le due sorgenti più comuni: un array statico di stringhe e un oggetto JSON le cui chiavi diventano le voci della combo.

unit ComboBoxPopulator;

interface

uses
  System.SysUtils, System.Classes, System.IOUtils, System.JSON, Vcl.StdCtrls;

type
  TComboBoxPopulator = class
  private
    FComboBox: TComboBox;
  public
    constructor Create(AComboBox: TComboBox);
    procedure PopulateFromArray(const Items: array of string);
    procedure PopulateFromJSON(const JSONFilePath: string);
  end;

implementation

constructor TComboBoxPopulator.Create(AComboBox: TComboBox);
begin
  FComboBox := AComboBox;
end;

procedure TComboBoxPopulator.PopulateFromArray(const Items: array of string);
var
  I: Integer;
begin
  FComboBox.Items.Clear;
  for I := Low(Items) to High(Items) do
    FComboBox.Items.Add(Items[I]);
end;

procedure TComboBoxPopulator.PopulateFromJSON(const JSONFilePath: string);
var
  JSONValue: TJSONValue;
  JSONObj: TJSONObject;
  I: Integer;
begin
  FComboBox.Items.Clear;
  if not TFile.Exists(JSONFilePath) then
    Exit;

  JSONValue := TJSONObject.ParseJSONValue(TFile.ReadAllText(JSONFilePath));
  try
    if JSONValue is TJSONObject then
    begin
      JSONObj := TJSONObject(JSONValue);
      for I := 0 to JSONObj.Count - 1 do
        FComboBox.Items.Add(JSONObj.Pairs[I].JsonString.Value);
    end;
  finally
    JSONValue.Free;
  end;
end;

end.

Da una query con filtro

Quando le voci arrivano da una tabella, spesso serve anche filtrarle prima di mostrarle: un cliente digita qualche lettera e la combo si aggiorna. Incapsulando dati e filtro in una classe basata su TClientDataSet, il form si limita a chiamare due metodi.

unit RecordTableUnit;

interface

uses
  System.SysUtils, Data.DB, Vcl.DBClient, Vcl.StdCtrls;

type
  TRecordTable = class
  private
    FDataSet: TClientDataSet;
  public
    constructor Create;
    destructor Destroy; override;
    procedure AddRecord(const ID: Integer; const Nome: string);
    procedure FilterRecords(const Filtro: string);
    procedure PopulateComboBox(const ComboBox: TComboBox);
  end;

implementation

constructor TRecordTable.Create;
begin
  FDataSet := TClientDataSet.Create(nil);
  FDataSet.FieldDefs.Add('ID', ftInteger);
  FDataSet.FieldDefs.Add('Nome', ftString, 50);
  FDataSet.CreateDataSet;
end;

destructor TRecordTable.Destroy;
begin
  FDataSet.Free;
  inherited;
end;

procedure TRecordTable.AddRecord(const ID: Integer; const Nome: string);
begin
  FDataSet.AppendRecord([ID, Nome]);
end;

procedure TRecordTable.FilterRecords(const Filtro: string);
begin
  FDataSet.Filter := Filtro;
  FDataSet.Filtered := not Filtro.IsEmpty;
end;

procedure TRecordTable.PopulateComboBox(const ComboBox: TComboBox);
begin
  ComboBox.Items.Clear;
  FDataSet.First;
  while not FDataSet.Eof do
  begin
    ComboBox.Items.Add(FDataSet.FieldByName('Nome').AsString);
    FDataSet.Next;
  end;
end;

end.

Un'unica regola da rispettare

Qualunque sia la sorgente, vale una regola semplice: la combo non deve mai sapere da dove arrivano i dati. Il form chiama PopulateFromArray, PopulateFromJSON o PopulateComboBox allo stesso modo, e la sorgente reale resta un dettaglio implementativo che si può cambiare senza toccare l'interfaccia. È un investimento minimo che ripaga rapidamente non appena la stessa combo va riusata in un secondo form.

Altri articoli su Delphi grid_viewTutte le tematiche
Scrivici su WhatsApp