我只得到了 first 部分的解决方案。由于原始源代码中奇怪的 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 是从没有前导 T 的 ColumnClass 构建的(例如 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 替换为 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
保存文件
自定义列
作为示例,我将使用从TStringColumn 派生的简单TNumberColumn。请记住,您必须注册您的自定义列类。
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 并运行程序以查看这些列是否对齐。
Complete Sample Project Source except the Fmx.Bind.GridAdv.pas