Delphi

Una TLabel che risolve da sola una chiave in un valore leggibile

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.

Quando in un form serve mostrare, accanto a un codice cliente o a un ID categoria, la relativa descrizione testuale, la soluzione più immediata è una DBLookupComboBox. Ma se quel valore va solo visualizzato — mai modificato dall'utente — un componente più leggero e a prova di click accidentale è una TLabel resa data-aware, che si aggiorna da sola quando il record corrente cambia.

Il meccanismo: TFieldDataLink

Il collegamento a un dataset in Delphi passa quasi sempre da un TFieldDataLink: si registra un gestore per l'evento OnDataEvent e si reagisce a deFieldChange, l'evento che scatta quando il valore del campo osservato cambia (nuovo record, modifica, scroll).

unit uCustomLookupLabel;

interface

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

type
  TCustomLookupLabel = class(TLabel)
  private
    FDataLink: TFieldDataLink;
    FLookupDataset: TClientDataSet;
    FLookupKeyField: string;
    FLookupResultField: string;
    procedure DataEvent(Event: TDataEvent; Info: NativeInt);
    function GetDataSource: TDataSource;
    procedure SetDataSource(Value: TDataSource);
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property LookupDataset: TClientDataSet read FLookupDataset write FLookupDataset;
    property LookupKeyField: string read FLookupKeyField write FLookupKeyField;
    property LookupResultField: string read FLookupResultField write FLookupResultField;
    property DataSource: TDataSource read GetDataSource write SetDataSource;
    property DataField: string read GetDataField write SetDataField;
  end;

implementation

constructor TCustomLookupLabel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FDataLink := TFieldDataLink.Create;
  FDataLink.OnDataEvent := DataEvent;
end;

destructor TCustomLookupLabel.Destroy;
begin
  FDataLink.Free;
  inherited;
end;

procedure TCustomLookupLabel.DataEvent(Event: TDataEvent; Info: NativeInt);
begin
  if (Event = deFieldChange) and Assigned(FDataLink.Field) then
  begin
    if not FDataLink.Field.IsNull and Assigned(FLookupDataset) and
       FLookupDataset.Locate(FLookupKeyField, FDataLink.Field.AsVariant, []) then
      Caption := FLookupDataset.FieldByName(FLookupResultField).AsString
    else
      Caption := '';
  end;
end;

function TCustomLookupLabel.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TCustomLookupLabel.SetDataSource(Value: TDataSource);
begin
  FDataLink.DataSource := Value;
  if Value <> nil then
    Value.FreeNotification(Self);
end;

end.

Una variante senza dataset di lookup

Non sempre conviene tenere aperto un secondo dataset solo per una manciata di coppie chiave-descrizione (uno stato, una categoria, un tipo documento). In questi casi lo stesso meccanismo può appoggiarsi a un array in memoria di coppie TPair<Integer, string> invece che a un TClientDataSet: la logica di DataEvent resta identica, cambia solo il modo in cui si cerca il valore corrispondente (un ciclo for..in sull'array al posto di Locate).

Registrarlo in palette

Aggiungendo una procedure Register che chiama RegisterComponents, il componente diventa disponibile nella palette dell'IDE come qualsiasi altro controllo VCL, pronto per essere trascinato su un form e collegato a DataSource, DataField e LookupDataset direttamente a design time — senza una riga di codice nel form che lo ospita.

Altri articoli su Delphi grid_viewTutte le tematiche
Scrivici su WhatsApp