Skip to main content

Using provider mode: Complete Code

  • 6 minutes to read
  1. Base class structure

  2. TPriceList

  3. TUserDataSource

  4. Creating columns

  5. Full code

5. Full code

The full code used to create a custom data source is listed below.

unit Unit1;
interface
uses
  SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls,
  cxCustomData, cxDataStorage, cxGrid, cxGridCustomTableView, cxGridTableView;
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FGrid: TcxGrid;
    FTableView: TcxGridTableView;
    procedure LoadValues();
  public
    property Grid: TcxGrid read FGrid;
  end;
var
  Form1: TForm1;
implementation
{$R *.dfm}
type
  { User Objects }
  PListEntry = ^TListEntry;
  TListEntry = packed record
    Description: string;
    OnHand: Integer;
    Price: Currency;
  end;
  TPriceList = class
  private
    FRecords: TList;
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(ADescription: string; AOnHand: Integer;
    APrice: Currency);
    procedure Clear;
  end;
  TUserDataSource = class(TcxCustomDataSource)
  private
    FPriceList: TPriceList;
    function GetDataBinding(AItemIndex: Integer):
    TcxGridItemDataBinding;
  protected
    function GetInfoForCompare(ARecordHandle: TcxDataRecordHandle;
    AItemHandle: TcxDataItemHandle; var PValueBuffer: PChar):
    Boolean; override;
    function GetItemHandle(AItemIndex: Integer): TcxDataItemHandle;
    override;
    function GetRecordCount: Integer; override;
    function GetValue(ARecordHandle: TcxDataRecordHandle;AItemHandle:
    TcxDataItemHandle): Variant; override;
    function IsNativeCompare: Boolean; override;
  public
    constructor Create(APriceList: TPriceList);
  end;
var
  PriceList: TPriceList;
{ TPriceList }
constructor TPriceList.Create;
begin
  FRecords := TList.Create;
end;
destructor TPriceList.Destroy;
begin
  Clear;
  FRecords.Free;
  inherited Destroy;
end;
procedure TPriceList.Add(ADescription: string; AOnHand: Integer; APrice: Currency);
var
  P: PListEntry;
begin
  New(P);
  FRecords.Add(P);
  P^.Description := ADescription;
  P^.OnHand := AOnHand;
  P^.Price := APrice;
end;
procedure TPriceList.Clear;
begin
  while FRecords.Count > 0 do
  begin
    Dispose(PListEntry(FRecords[FRecords.Count - 1]));
    FRecords.Delete(FRecords.Count - 1);
  end;
end;
{ TUserDataSource }
constructor TUserDataSource.Create(APriceList: TPriceList);
begin
  inherited Create;
  FPriceList := APriceList;
end;
function TUserDataSource.GetDataBinding(AItemIndex: Integer): TcxGridItemDataBinding;
begin
  Result := TcxCustomGridTableItem(DataController.GetItem(AItemIndex)).DataBinding;
end;
function TUserDataSource.GetInfoForCompare(ARecordHandle: TcxDataRecordHandle;
  AItemHandle: TcxDataItemHandle; var PValueBuffer: PChar): Boolean;
var
  ADataBinding: TcxGridItemDataBinding;
begin
  ADataBinding := TcxGridItemDataBinding(AItemHandle);
  PValueBuffer := PChar(Integer(FPriceList.
  FRecords[Integer(ARecordHandle)]) +
  Integer(ADataBinding.Data));
  Result := True;
end;
function TUserDataSource.GetItemHandle(AItemIndex: Integer): TcxDataItemHandle;
begin
  Result := TcxDataItemHandle(GetDataBinding(AItemIndex));
end;
function TUserDataSource.GetRecordCount: Integer;
begin
  Result := FPriceList.FRecords.Count;
end;
function TUserDataSource.GetValue(ARecordHandle: TcxDataRecordHandle; AItemHandle: TcxDataItemHandle): Variant;
var
  P: PChar;
  ADataBinding: TcxGridItemDataBinding;
begin
  ADataBinding := TcxGridItemDataBinding(AItemHandle);
  P := PChar(Integer(FPriceList.FRecords[Integer(ARecordHandle)]) +
  Integer(ADataBinding.Data));
  Result := ADataBinding.ValueTypeClass.GetValue(P);
end;
function TUserDataSource.IsNativeCompare: Boolean;
begin
  Result := True;
end;
{ routines }
procedure GenerateColumns(AGridTableView: TcxGridTableView);
var
  AListEntry: TListEntry;
begin
  with AGridTableView do
  begin
    OptionsSelection.HideFocusRect := False;
    OptionsSelection.MultiSelect := True;
    ClearItems;
    with CreateColumn as TcxGridColumn do
    begin
      Caption := 'Description';
      DataBinding.ValueTypeClass := TcxStringValueType;
      DataBinding.Data := Pointer(0);
      Width := 100;
    end;
    with CreateColumn as TcxGridColumn do
    begin
      Caption := 'OnHand';
      DataBinding.ValueTypeClass := TcxIntegerValueType;
      DataBinding.Data := Pointer(Integer(@AListEntry.OnHand) -
      Integer(@AListEntry));
      Width := 100;
    end;
    with CreateColumn as TcxGridColumn do
    begin
      Caption := 'Price';
      DataBinding.ValueTypeClass := TcxCurrencyValueType;
      DataBinding.Data := Pointer(Integer(@AListEntry.Price) -
      Integer(@AListEntry));
      Width := 100;
    end;
  end;
end;
procedure TForm1.LoadValues();
begin
  PriceList.Add('Dive kayak', 24, 3999.95);
  PriceList.Add('Underwater Diver Vehicle', 5, 1680.00);
  PriceList.Add('Regulator System', 165, 250.00);
  PriceList.Add('Personal Dive Sonar', 46, 235.00);
  PriceList.Add('Depth/Pressure Gauge', 128, 206.00);
  FTableView.DataController.CustomDataSource.DataChanged;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
  FGrid := TcxGrid.Create(Self);
  with FGrid do
  begin
    FTableView := CreateView(TcxGridTableView) as TcxGridTableView;
    Levels.Add.GridView := FTableView;
    GenerateColumns(FTableView);
    FTableView.OptionsView.Footer := True;
    with FTableView.DataController.Summary.FooterSummaryItems.Add do
    begin
      Kind := skCount;
      ItemLink := FTableView.Columns[0];
    end;
    Align := alClient;
    Parent := Self;
  end;
  FTableView.DataController.CustomDataSource :=
  TUserDataSource.Create(PriceList);
  LoadValues();
end;
initialization
  PriceList := TPriceList.Create;
finalization
  PriceList.Free;
end.
See Also