I only got a solution to the first part. It's a little bit tricky because of the weird ColumnCreate implementation in the original source.
What's the reason?
Have a look at unit Fmx.Bind.Grid
(path on Win32 %programfiles%\Embarcadero\RAD Studio\10.0\source\databinding\components
) and method (starts at line 500)
function TLinkGridToDataSourceControlManager.CreateColumn(
const ADescription : TCreateColumnDescription; AGrid : TCustomGrid ) : TColumn;
The Columns are created in relation to ADescription.ColumnStyle
or if empty on ADescription.MemberType
. But it is not based on registered classes, it's hard coded.
This is weird, because the ColumnStyleName is build from the ColumnClass without the leading T
(e.g. Class TStringColumn
=> ColumnStyle StringColumn
).
Why didn't Emba just search for registered Classes based on ColumnStyle?
FindClass( 'T' + ADescription.ColumnStyle )
If so, you were able to register your own ColumnClasses TMyColumn
, set the ColumnStyle property to MyColumn
and everything would be fine. You were not able to see this ColumnStyle in the PropertyEditor unless you install this ColumnClass as a package (no, this wont work, because PropertyEditor is also hard coded), but who cares about that it can be set inside OI.
Let's get flexible
To get this fixed you have to do some steps by hand
- Copy
Fmx.Bind.Grid.pas
to new path (project did or a valid Delphi Search/Library Path)
- Rename it to
Fmx.Bind.GridAdv.pas
Now you have to replace Fmx.Bind.Grid
to Fmx.Bind.GridAdv
at lines in this copy
line 9, 10, 455
To get the flexibility inside replace this (starting at line 500)
function TLinkGridToDataSourceControlManager.CreateColumn(
const ADescription: TCreateColumnDescription; AGrid: TCustomGrid): TColumn;
begin
Result := nil;
if ADescription.ColumnStyle <> '' then
with this
function TLinkGridToDataSourceControlManager.CreateColumn(
const ADescription : TCreateColumnDescription; AGrid : TCustomGrid ) : TColumn;
// ** MOD START **
type
TColumnClass = class of TColumn;
var
LColumnClass : TColumnClass;
// ** MOD END **
begin
Result := nil;
if ADescription.ColumnStyle <> '' then
// ** MOD START **
begin
LColumnClass := TColumnClass( FindClass( 'T' + ADescription.ColumnStyle ) );
if LColumnClass <> nil
then
begin
Result := LColumnClass.Create( FCustomGrid );
end else
// ** MOD END **
and some lines below we have to close the begin
// ** MOD START **
end;
// ** MOD END **
if Result = nil then
case ADescription.MemberType of
Save the file
Custom Column
As a sample i will use a simple TNumberColumn
derived from TStringColumn
. Remember you have to register your custom column classes.
unit FMX.Grid.Columns;
interface
uses
FMX.Grid, FMX.Types, FMX.Menus;
type
TNumberColumn = class( TStringColumn )
protected
function CreateCellControl : TStyledControl; override;
end;
implementation
{ TNumberColumn }
function TNumberColumn.CreateCellControl : TStyledControl;
begin
Result := inherited;
( Result as TTextCell ).TextAlign := TTextAlign.taTrailing;
end;
initialization
RegisterFmxClasses( [TNumberColumn] );
end.
How to use?
Just create your forms as usual and create your bindings with the grid for some columns.
To get our patch running you have to take care of the uses order. The patched unit has to be after the original unit.
unit Main_ViewU;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Rtti, System.Classes,
System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.Grid,
FMX.Layouts, Data.Bind.GenData, Data.Bind.EngExt, FMX.Bind.DBEngExt,
FMX.Bind.Grid, // <-- original unit
FMX.Bind.GridAdv, // <-- patched unit
FMX.Grid.Columns, // CustomColumns unit
System.Bindings.Outputs, FMX.Bind.Editors,
Data.Bind.Components, Data.Bind.Grid, Data.Bind.ObjectScope;
type
TForm1 = class( TForm )
Grid1 : TGrid;
DataGeneratorAdapter1 : TDataGeneratorAdapter;
AdapterBindSource1 : TAdapterBindSource;
BindingsList1 : TBindingsList;
LinkGridToDataSource1 : TLinkGridToDataSource;
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1 : TForm1;
implementation
{$R *.fmx}
end.
Last step, just set for some Columns the ColumnStyle
to NumberColumn
and run the program to see theses columns aligned right.
Complete Sample Project Source except the Fmx.Bind.GridAdv.pas