我只有第一部分的解决方案。由于原始源代码中奇怪的 ColumnCreate 实现,这有点棘手。
什么原因?
查看单元Fmx.Bind.Grid
(Win32 上的路径%programfiles%\Embarcadero\RAD Studio\10.0\source\databinding\components
)和方法(从第 500 行开始)
function TLinkGridToDataSourceControlManager.CreateColumn(
const ADescription : TCreateColumnDescription; AGrid : TCustomGrid ) : TColumn;
列是相对于ADescription.ColumnStyle
或如果为空而创建的ADescription.MemberType
。但它不是基于注册的类,它是硬编码的。
这很奇怪,因为 ColumnStyleName 是从没有前导的 ColumnClass 构建的T
(例如 Class TStringColumn
=> ColumnStyle StringColumn
)。
为什么 Emba 不直接根据 ColumnStyle 搜索已注册的 Classes?
FindClass( 'T' + ADescription.ColumnStyle )
如果是这样,您可以注册自己的 ColumnClasses TMyColumn
,将 ColumnStyle 属性设置为MyColumn
,一切都会好起来的。您无法在 PropertyEditor 中看到此 ColumnStyle,除非您将此 ColumnClass 作为包安装(不,这不会起作用,因为 PropertyEditor 也是硬编码的),但谁在乎它可以在 OI 中设置。
让我们变得灵活
要解决此问题,您必须手动执行一些步骤
- 复制
Fmx.Bind.Grid.pas
到新路径(项目确实或有效的 Delphi 搜索/库路径)
- 将其重命名为
Fmx.Bind.GridAdv.pas
现在您必须在此副本中替换Fmx.Bind.Grid
为at 行Fmx.Bind.GridAdv
9、10、455 号线
为了获得内部的灵活性,请替换它(从第 500 行开始)
function TLinkGridToDataSourceControlManager.CreateColumn(
const ADescription: TCreateColumnDescription; AGrid: TCustomGrid): TColumn;
begin
Result := nil;
if ADescription.ColumnStyle <> '' then
有了这个
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 **
下面的一些行我们必须关闭begin
// ** MOD START **
end;
// ** MOD END **
if Result = nil then
case ADescription.MemberType of
保存文件
自定义列
作为示例,我将使用一个简单的TNumberColumn
衍生自TStringColumn
. 请记住,您必须注册自定义列类。
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.
如何使用?
只需像往常一样创建表单并使用网格为某些列创建绑定。
要让我们的补丁运行,您必须注意使用顺序。修补的单元必须在原始单元之后。
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.
最后一步,只需将某些列设置为ColumnStyle
并NumberColumn
运行程序以查看这些列是否正确对齐。
除了 Fmx.Bind.GridAdv.pas 之外的完整示例项目源