I'm using the RAD Studio LiveBindings demo and have created a TGender Enum for the TPerson, which I want displayed as a string instead in a grid. I'm using the TListBindSourceAdapter as the data is stored in a TObjectList. I have created a TConverterDescription and registered it, but the Enum is still showing up as an integer in the grid. How can this be shown as a string automatically, without adding addition "EnumDescription" or similar fields on the class itself? Sample source code below (based on Delphi samples):
uMain.pas
unit uMain;
interface
uses
Spring.Data.ObjectDataSet,
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
Data.Bind.EngExt, Fmx.Bind.DBEngExt, Data.Bind.Components,
Data.Bind.ObjectScope, CollectionObjects, System.Rtti, Fmx.Bind.Grid,
System.Bindings.Outputs, Fmx.Bind.Editors, Data.Bind.Grid, FMX.Layouts,
FMX.Grid, FMX.Controls.Presentation, FMX.StdCtrls,
System.Generics.Collections, REST.JSON,
Data.Bind.GenData, FMX.ScrollBox, FMX.Memo, FMX.TabControl,
Data.Bind.Controls, Fmx.Bind.Navigator, FMX.Grid.Style, System.JSON, FMX.Memo.Types;
type
TGender = (Male, Female, NonBinary);
TPerson = class
private
FAge: Integer;
FLastName: string;
FFirstName: string;
FGender: TGender;
public
constructor Create(FirstName, LastName: String; Age: Integer; Gender: TGender);
property FirstName: string read FFirstName write FFirstName;
property LastName: string read FLastName write FLastName;
property Age: Integer read FAge write FAge;
property Gender: TGender read FGender write FGender;
end;
TMainForm = class(TForm)
AdapterBindSource1: TAdapterBindSource;
BindingsList1: TBindingsList;
TabControl1: TTabControl;
GridTab: TTabItem;
Grid1: TGrid;
LinkGridToDataSourceAdapterBindSource12: TLinkGridToDataSource;
DataGeneratorAdapter1: TDataGeneratorAdapter;
NavigatorAdapterBindSource1: TBindNavigator;
procedure AdapterBindSource1CreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
private
fMyPeople: TObjectList<TPerson>;
fMyPeopleDB: TObjectDataSet;
public
end;
var
MainForm: TMainForm;
implementation
{$R *.fmx}
{$R *.LgXhdpiPh.fmx ANDROID}
{$R *.iPhone4in.fmx IOS}
constructor TPerson.Create(FirstName, LastName: String; Age: Integer; Gender: TGender);
begin
FFirstName := FirstName;
FLastName := LastName;
FAge := Age;
FGender := Gender;
end;
procedure TMainForm.AdapterBindSource1CreateAdapter(Sender: TObject;
var ABindSourceAdapter: TBindSourceAdapter);
begin
// A collection that owns the TPerson objects
fMyPeople := TObjectList<TPerson>.Create;
// The individual TPerson objects
fMyPeople.Add(TPerson.Create('Gomez', 'Addams', 40, Male));
fMyPeople.Add(TPerson.Create('Morticia', 'Addams', 38, Female));
fMyPeople.Add(TPerson.Create('Pugsley', 'Addams', 8, NonBinary));
fMyPeople.Add(TPerson.Create('Wednesday', 'Addams', 12, NonBinary));
fMyPeople.Add(TPerson.Create('Uncle', 'Fester', 55, Male));
fMyPeople.Add(TPerson.Create('Grandmama', 'Frump', 72, Female));
fMyPeople.Add(TPerson.Create('', 'Lurch', 50, Male));
fMyPeople.Add(TPerson.Create('Thing T.', 'Thing', 99, NonBinary));
fMyPeople.Add(TPerson.Create('Cousin', 'Itt', 21, NonBinary));
// Use TObjectBindSourceAdapter for a single object
ABindSourceAdapter := TListBindSourceAdapter<TPerson>.Create(Self, fMyPeople, True);
end;
procedure RegisterConverters;
begin
TValueRefConverterFactory.RegisterConversion(TypeInfo(TGender), TypeInfo(string),
TConverterDescription.Create(
procedure(const InValue: TValue; var OutValue: TValue)
begin
case InValue.AsType<TGender> of
Female: OutValue := TValue.From<string>('Female');
NonBinary: OutValue := TValue.From<string>('Non Binary');
else
OutValue := TValue.From<string>('Male');
end;
end,
'TGenderToString', 'TGenderToString', EmptyStr, True, EmptyStr, nil)
);
end;
initialization
RegisterConverters;
end.
uMain.fmx
object MainForm: TMainForm
Left = 0
Top = 0
Caption = 'Adapter Bind Source - Bidirectional object binding'
ClientHeight = 480
ClientWidth = 640
FormFactor.Width = 320
FormFactor.Height = 480
FormFactor.Devices = [Desktop]
DesignerMasterStyle = 0
object TabControl1: TTabControl
Align = Client
Size.Width = 640.000000000000000000
Size.Height = 480.000000000000000000
Size.PlatformDefault = False
TabIndex = 0
TabOrder = 3
TabPosition = PlatformDefault
Sizes = (
640s
454s)
object GridTab: TTabItem
CustomIcon = <
item
end>
IsSelected = True
Size.Width = 43.000000000000000000
Size.Height = 26.000000000000000000
Size.PlatformDefault = False
StyleLookup = ''
TabOrder = 0
Text = 'Grid'
ExplicitSize.cx = 42.000000000000000000
ExplicitSize.cy = 26.000000000000000000
object Grid1: TGrid
Align = Client
CanFocus = True
ClipChildren = True
Size.Width = 640.000000000000000000
Size.Height = 429.000000000000000000
Size.PlatformDefault = False
TextSettings.Font.Size = 18.000000000000000000
StyledSettings = [Family, Style, FontColor]
TabOrder = 1
RowHeight = 30.000000000000000000
RowCount = 9
Viewport.Width = 636.000000000000000000
Viewport.Height = 404.000000000000000000
end
object NavigatorAdapterBindSource1: TBindNavigator
Align = Top
Margins.Left = 10.000000000000000000
Margins.Right = 10.000000000000000000
Position.X = 10.000000000000000000
Size.Width = 620.000000000000000000
Size.Height = 25.000000000000000000
Size.PlatformDefault = False
TabOrder = 0
DataSource = AdapterBindSource1
VisibleButtons = [nbFirst, nbPrior, nbNext, nbLast, nbInsert, nbDelete, nbEdit, nbPost, nbCancel]
xRadius = 4.000000000000000000
yRadius = 4.000000000000000000
ConfirmDelete = False
end
end
end
object AdapterBindSource1: TAdapterBindSource
AutoActivate = True
OnCreateAdapter = AdapterBindSource1CreateAdapter
Adapter = DataGeneratorAdapter1
ScopeMappings = <>
Left = 368
Top = 376
end
object BindingsList1: TBindingsList
Methods = <>
OutputConverters = <>
Left = 492
Top = 373
object LinkGridToDataSourceAdapterBindSource12: TLinkGridToDataSource
Category = 'Quick Bindings'
DataSource = AdapterBindSource1
GridControl = Grid1
Columns = <
item
MemberName = 'FirstName'
Width = 120
end
item
MemberName = 'LastName'
Width = 200
end
item
MemberName = 'Age'
Width = 32
end
item
MemberName = 'Gender'
end>
end
end
object DataGeneratorAdapter1: TDataGeneratorAdapter
FieldDefs = <
item
Name = 'FirstName'
Generator = 'LoremIpsum'
ReadOnly = False
end
item
Name = 'LastName'
Generator = 'LoremIpsum'
ReadOnly = False
end
item
Name = 'Age'
FieldType = ftInteger
Generator = 'Integers'
ReadOnly = False
end
item
Name = 'Gender'
Generator = 'LoremIpsum'
ReadOnly = False
end>
Active = True
AutoPost = False
RecordCount = 9
Options = [loptAllowInsert, loptAllowDelete, loptAllowModify]
Left = 216
Top = 376
end
end