Migrate from TDBGrid and cxGrid to sgcGrid

sgcGrid is a VCL data grid, TsgcVCLGrid, that binds to any TDataSet and brings grouping, summaries, filtering, a find panel, bands and saved layouts to every edition. This kit maps each TDBGrid and cxGrid member you use to its sgcGrid twin, shows the code from a compiled demo, and lists honestly what does not map.

Two Starting Points, One Grid

Delphi VCL teams on the stock TDBGrid, and teams on the DevExpress cxGrid who review the subscription.

From TDBGrid

The stock VCL TDBGrid shows and edits a dataset, and that is where it stops. It has no filter row, no column filter, no grouping, no footer or group summaries, no find panel, no bands, no best fit and no layout save and load. Each of those is custom code or a third party grid. sgcGrid gives you all of them in one control, bound to the dataset you already have.

From cxGrid

The DevExpress cxGrid (ExpressQuantumGrid) is a broad and mature grid. Teams that use it mostly as a table view with grouping, summaries, filtering and saved layouts can cover that set with sgcGrid, with full source code, and drop a subscription that covers far more than the grid.

What the grid costs today: on 2026-10-20 the DevExpress VCL price list offered three subscriptions, all of them with the ExpressQuantumGrid Control. The lowest is the Express QuantumPack at USD 999.99, the VCL Subscription is USD 1,699.99. In a Delphi-PRAXiS thread of 18 September 2025 a user reported his cxGrid subscription going from USD 400 to USD 550, and another member quoted a DevExpress announcement that new Express GridPack licenses are no longer sold (active subscribers can still renew). sgcGrid is licensed per developer from €199 with full source code and one year of updates, and it is also part of every sgcUI edition.

One Control, Bound to Any TDataSet

A TsgcVCLGrid and a TsgcGridSource_DataSet with DataSet, Grid and KeyField. The dataset events keep the grid in step.

In every edition

Designed columns matched by FieldName, lookup fields, cell, row and multi row selection, row header, custom draw, Ctrl+C, group panel, footer and group summaries, filter row, Excel style column filter, find panel, bands, best fit, and JSON layout save and load.

Registered edition only

Two way editing into the dataset (WriteBack), cursor sync (SyncCursor), insert, delete, paste and undo, the card view (ViewStyle) and server mode for very large tables. The trial includes them for evaluation. The Community build leaves them out: the demo still compiles there and shows its grids read only.

TDBGrid Members, sgcGrid Equivalents

Every sgcGrid name below is in the shipped source, and the ones the demo uses compile in it.

TDBGrid sgcGrid Edition
TDBGridTsgcVCLGrid (unit sgcGrid_VCL)All
DataSourceTsgcGridSource_DataSet: DataSet, Grid, KeyField, then Active := True (unit sgcGrid_Source_DataSet)All
Columns, TColumn.FieldNameColumns, Columns[i].FieldName. Designed columns are kept and matched by FieldName; with no columns, AutoColumns creates themAll
Title.Caption, Width, VisibleColumns[i].Caption, Width, VisibleAll
TColumn.ReadOnlyColumns[i].EditableAll (editing: Registered)
TColumn.PickList, lookup field drop downColumns[i].PickList; for a lookup field the source fills the list from the LookupDataSetAll (writing the value: Registered)
TField.DisplayFormatColumns[i].DisplayFormatAll
ReadOnly, Options dgEditingTsgcVCLGrid.ReadOnly (default True) and TsgcGridSource_DataSet.WriteBackRegistered
dgRowSelectSelectionMode := gsmRow (gsmCell without it)All
dgMultiSelect, SelectedRowsSelectionMode := gsmMultiRow; SelectedRows, SelectedRowCount, GetSelectedKeys, RowSelected[]All
dgIndicatorRowHeader := [grhIndicator] (also grhNumbers, grhCheckBox)All
dgColLines, dgRowLinesGridLinesV, GridLinesHAll
Current record follows the gridTsgcGridSource_DataSet.SyncCursorRegistered
OnDrawColumnCell, DefaultDrawColumnCellOnCustomDrawCell with aDefaultDraw; for colours only, OnGetCellStyle or FormatRulesAll
OnTitleClickOnHeaderClickAll
Ctrl+C (custom code)Built in (Ctrl+C, Ctrl+Ins); the text comes from SelectionToTextAll
Insert and Ctrl+Del keysAllowInsert, AllowDelete, InsertRow, DeleteSelectedRows, OnBeforeDeleteRegistered

cxGrid Members, sgcGrid Equivalents

The cxGrid names are DevExpress identifiers, given for orientation only.

cxGrid sgcGrid Edition
TcxGridDBTableView, DataController.DataSourceTsgcVCLGrid and TsgcGridSource_DataSetAll
TcxGridDBColumn.DataBinding.FieldNameColumns[i].FieldNameAll
TcxGridDBColumn.GroupIndexColumns[i].GroupIndex; GroupBy(['Field']), ClearGrouping, GroupCountAll
OptionsView.GroupByBoxShowGroupPanelAll
DataController.Groups.FullExpand, FullCollapseExpandAll, CollapseAllAll
OptionsView.FooterShowFooterAll
DataController.Summary.FooterSummaryItems (skSum, skCount, skAverage, skMin, skMax)Columns[i].SummaryType (gsuSum, gsuCount, gsuAverage, gsuMin, gsuMax), SummaryFormat; values from FooterSummary(aCol), FooterSummaryText(aCol); SummaryScopeAll
DataController.Summary.DefaultGroupSummaryItemsGroupSummaries, using the column SummaryType in the groupsAll
FilterRow.VisibleShowFilterRow, Columns[i].FilterRowOperatorAll
Column filter drop downShowFilterButtons, ShowFilterPopup(aCol), ClearColumnFilter(aCol), ClearColumnFilters, OnFilterChangeAll
FindPanel.DisplayModeShowFindPanel, FindText, FindNext, FindPrevious, FindOnlyMatchesAll
TcxGridDBBandedTableView.Bands, Column.Position.BandIndexBands (Caption, ParentBand, Visible), Columns[i].BandAll
ApplyBestFitBestFitColumns, BestFitColumn(aCol), BestFitOnDblClick, BestFitSampleRowsAll
StoreToIniFile, RestoreFromIniFileSaveLayoutToFile, LoadLayoutFromFile (JSON), also to and from a string or a stream; automatic with AutoSaveLayout and LayoutStorageKeyAll
OptionsCustomize.ColumnMovingColumnMovingAll
Column customization dialogShowColumnChooserAll
OnCustomDrawCellOnCustomDrawCellAll
TcxGridDBCardView (a second view)ViewStyle := gvsCard on the same grid, CardOptions (CaptionField, CardWidth, CardHeight, ShowFieldCaptions)Registered

The Code, From the Compiled Demo

Each excerpt is copied from the MigrateFromDBGrid demo, which compiles with Delphi 7 and Delphi 13 (Win32 and Win64). The comments name the TDBGrid or cxGrid code it replaces.

Binding: DataSource becomes a TsgcGridSource_DataSet

Before: a TDBGrid with DataSource := dsProducts. After: the source component on the form.

frmMain.dfm
object SourceDB: TsgcGridSource_DataSet
  DataSet = cdsProducts
  Grid = GridDB
  KeyField = 'ID'
  Left = 280
  Top = 520
end

TDBGrid options become properties

Before: Options with dgEditing, dgRowSelect, dgMultiSelect and dgIndicator. After:

frmMain.pas
procedure TFormMain.chkOptionsClick(Sender: TObject);
begin
  // TDBGrid.ReadOnly / Options dgEditing -> ReadOnly
{$IFDEF SGC_GRID_EDIT}
  GridDB.ReadOnly := not chkEditing.Checked;
{$ENDIF}
  // dgMultiSelect -> gsmMultiRow, dgRowSelect -> gsmRow, neither -> gsmCell
  if chkMultiSelect.Checked then
    GridDB.SelectionMode := gsmMultiRow
  else if chkRowSelect.Checked then
    GridDB.SelectionMode := gsmRow
  else
    GridDB.SelectionMode := gsmCell;
  // dgIndicator -> RowHeader [grhIndicator] (grhNumbers, grhCheckBox too)
  if chkIndicator.Checked then
    GridDB.RowHeader := [grhIndicator]
  else
    GridDB.RowHeader := [];
end;

OnDrawColumnCell becomes OnCustomDrawCell

Before: OnDrawColumnCell reading Column.FieldName and the field value. After: aCol is the Columns index and aRow the view row of Data (CS_LOW_STOCK is a constant of the demo).

frmMain.pas
procedure TFormMain.GridDBCustomDrawCell(Sender: TObject; aCanvas: TsgcUICanvas;
  aRow, aCol, aLeft, aTop, aRight, aBottom: Integer;
  aState: TsgcGridCellDrawStates; var aDefaultDraw: Boolean);
begin
  // TDBGrid.OnDrawColumnCell: Column.FieldName and Field.AsInteger.
  // sgcGrid: aCol is the Columns index, aRow the view row of Data. The
  // background is painted already; aDefaultDraw False would skip the text
  if (aRow < 0) or (aRow >= GridDB.Data.ViewCount) or
    (GridDB.Columns[aCol].FieldName <> 'Qty') then
    Exit;
  if StrToIntDef(VarToStr(GridDB.Data.Cells[aRow, aCol]), 0) < CS_LOW_STOCK
  then
  begin
    // a red marker at the left edge of a low stock cell
    aCanvas.BeginPath;
    aCanvas.Rectangle(aLeft, aTop + 4, aLeft + 4, aBottom - 4);
    aCanvas.ClosePath;
    aCanvas.FillPath($FFDC2626);
  end;
end;

Write back, cursor sync and grouping

Before: dgEditing on the TDBGrid, and a column dragged to the cxGrid GroupByBox. After:

frmMain.pas
procedure TFormMain.FormCreate(Sender: TObject);
begin
  DoCreateData;
  // TDBGrid: DataSource := dsProducts. sgcGrid: a TsgcGridSource_DataSet
  // with DataSet, Grid and KeyField (set on the form). The grid columns are
  // designed on the form like TDBGrid.Columns, matched by FieldName
{$IFDEF SGC_GRID_EDIT}
  // TDBGrid dgEditing posts edits to the dataset: WriteBack. The current
  // record follows the focused row and back: SyncCursor
  SourceDB.WriteBack := True;
  SourceDB.SyncCursor := True;
{$ELSE}
  chkEditing.Checked := False;
  chkEditing.Enabled := False;
  chkEditing.Caption := 'Editing (Registered edition)';
  GridDB.ReadOnly := True;
{$ENDIF}
  SourceDB.Active := True;
  SourceCx.Active := True;
  chkOptionsClick(nil);
  // cxGrid: drag a column to the GroupByBox. sgcGrid: ShowGroupPanel, and
  // GroupBy from code (cxGridDBColumn.GroupIndex is Columns[i].GroupIndex)
  GridCx.GroupBy(['Category']);

cxGrid table view features at design time

Before: footer summary items, the group by box, the filter row, the find panel and a banded table view. After: column properties and grid properties on the form.

frmMain.dfm
Columns = <
  item
    FieldName = 'ID'
    Caption = 'ID'
    DataType = gdtInteger
    Width = 60
    SummaryType = gsuCount
    Band = 0
  end
  item
    FieldName = 'Product'
    Caption = 'Product'
    Width = 220
    Band = 0
  end
  item
    FieldName = 'Category'
    Caption = 'Category'
    Width = 140
    Band = 0
  end
  item
    FieldName = 'Price'
    Caption = 'Price'
    DataType = gdtFloat
    Width = 110
    DisplayFormat = '#,##0.00'
    SummaryType = gsuAverage
    SummaryFormat = '#,##0.00'
    Band = 1
  end
  item
    FieldName = 'Qty'
    Caption = 'Qty'
    DataType = gdtInteger
    Width = 90
    SummaryType = gsuSum
    Band = 1
  end>
FormatRules = <>
ShowFooter = True
ShowGroupPanel = True
GroupSummaries = True
ShowFilterButtons = True
ShowFilterRow = True
ShowFindPanel = True
Bands = <
  item
    Caption = 'Product'
  end
  item
    Caption = 'Stock and price'
  end>

Best fit, layout and card view

Before: ApplyBestFit, StoreToIniFile, RestoreFromIniFile and a TcxGridDBCardView. After:

frmMain.pas
procedure TFormMain.btnBestFitClick(Sender: TObject);
begin
  // cxGridDBTableView.ApplyBestFit -> BestFitColumns (BestFitColumn(i) for
  // one column, BestFitOnDblClick for the header divider)
  GridCx.BestFitColumns;
end;

function TFormMain.DoLayoutFile: string;
begin
  Result := ExtractFilePath(ParamStr(0)) + 'migratefromdbgrid_layout.json';
end;

procedure TFormMain.btnSaveLayoutClick(Sender: TObject);
begin
  // cxGridDBTableView.StoreToIniFile -> SaveLayoutToFile (JSON: columns,
  // widths, order, sort, grouping, filters, summaries, bands, view)
  GridCx.SaveLayoutToFile(DoLayoutFile);
  DoShowStatus('layout saved to ' + ExtractFileName(DoLayoutFile));
end;

procedure TFormMain.btnLoadLayoutClick(Sender: TObject);
begin
  // cxGridDBTableView.RestoreFromIniFile -> LoadLayoutFromFile
  if GridCx.LoadLayoutFromFile(DoLayoutFile) then
    DoShowStatus('layout loaded')
  else
    DoShowStatus('no saved layout');
end;

procedure TFormMain.chkCardViewClick(Sender: TObject);
begin
{$IFDEF SGC_GRID_ADVANCED}
  // cxGridDBCardView (a second view of the level) -> ViewStyle gvsCard of
  // the same grid, CardOptions for the caption field and the card size
  if chkCardView.Checked then
    GridCx.ViewStyle := gvsCard
  else
    GridCx.ViewStyle := gvsTable;
{$ENDIF}
end;

Seven Steps per Form

The data layer stays as it is. Only the grid and its options change.

1

Drop the components

Install the sgcGrid packages, then drop a TsgcVCLGrid and a TsgcGridSource_DataSet on the form.

2

Point at the dataset

Set the source DataSet to the dataset the old grid used (the grid no longer needs the TDataSource), then Grid and KeyField, a unique field needed for in place updates and write back.

3

Recreate the columns

Add Columns with FieldName, Caption, Width, DisplayFormat and Editable, or leave Columns empty and let AutoColumns build them from the fields.

4

Map the options

ReadOnly and WriteBack for dgEditing, SelectionMode for dgRowSelect and dgMultiSelect, RowHeader for dgIndicator, SyncCursor for the current record.

5

Move the drawing code

Move OnDrawColumnCell code to OnCustomDrawCell, or to OnGetCellStyle when it only sets colours.

6

Switch on the cxGrid features

ShowGroupPanel, ShowFooter, GroupSummaries, ShowFilterRow, ShowFilterButtons, ShowFindPanel; summaries to Columns[i].SummaryType, bands to Bands and Columns[i].Band, layouts to SaveLayoutToFile.

7

Activate

Set Active := True on the source once the dataset is open.

What Does Not Map One to One

Read this before you plan the move.

MigrateFromDBGrid

One TClientDataSet of 40 products, with a Category lookup field, shown on two pages: "From TDBGrid" and "From cxGrid".

Where it is

The sgcUI installer puts it in Demos\Grid\Delphi\MigrateFromDBGrid: MigrateFromDBGrid.dpr, frmMain.pas, frmMain.dfm and a readme.html.

How to run it

Open MigrateFromDBGrid.dpr in any Delphi from 7 to 13, build Win32 or Win64 and run. Each page names the TDBGrid or cxGrid concept next to its sgcGrid equivalent.

Self test

MigrateFromDBGrid.exe /test checks the column and option mapping, the copy text, grouping, the footer summary, bands, the layout round trip and, in the Registered edition, write back and the card view, then exits with 0 when every check passed.

To be fair to both grids: cxGrid offers things sgcGrid does not, such as several views and levels in one grid control and INI layouts, and it comes with a large suite of other controls. If your application depends on those, the move is bigger than this page shows. sgcGrid is the path when the grid features listed above are what you use, and you want them with full source code, in Delphi 7 to 13, as a single product. For the full feature list see the sgcGrid product page.

Best value: All-AccessEvery eSeGeCe product, Premium Support included, from €1,059/year.
See All-Access pricing

Move Your First Grid Today

Download the sgcUI trial with sgcGrid and the MigrateFromDBGrid demo, and port your first form.