Обратите внимание, что этот пост можно рассматривать как дубликат как чтобы (правильно) использовать перечисляемый тип с livebindings (TObjectBindSourceAdapter).
Поскольку я считаю его ответ неверным, я публикую его другим способом.
Краткое изложение проблемы следующее:
Перечисленные TObject
свойства, которые должны быть адаптированы TObjectBindSourceAdapter
, не зарегистрированы успешно.
=> Вопрос: как успешно адаптировать TObject
с перечисленными полями к TObjectBindSourceAdapter
?
Если углубиться, рассмотрите следующее консольное приложение:
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils
, Data.Bind.Components
, Data.Bind.ObjectScope, Vcl.Bind.GenData, Data.Bind.Controls
, System.Rtti
;
type
TMyEnum = (one, two);
TMyObject = class
private
FIntField1: Integer;
FStrField2: String;
FEnumField3: TMyEnum;
procedure SetIntField1(const Value: Integer);
procedure SetStrField2(const Value: String);
procedure SetEnumField3(const Value: TMyEnum);
published
property IntField1: Integer read FIntField1 write SetIntField1;
property StrField2: String read FStrField2 write SetStrField2;
property EnumField3: TMyEnum read FEnumField3 write SetEnumField3;
end;
{ TMyObject }
procedure TMyObject.SetEnumField3(const Value: TMyEnum);
begin
FEnumField3 := Value;
end;
procedure TMyObject.SetIntField1(const Value: Integer);
begin
FIntField1 := Value;
end;
procedure TMyObject.SetStrField2(const Value: String);
begin
FStrField2 := Value;
end;
function GetMemberName(AValue: TBindSourceAdapterField): String;
begin
result := '?';
if AValue <> nil then
result := AValue.MemberName;
end;
var
lInternalBindSourceAdapter: TBindSourceAdapter;
lMyObject: TMyObject;
lRttiType: TRttiType;
LContext: TRttiContext;
lRttiProperties: TArray<TRttiProperty>;
lRttiProperty: TRttiProperty;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
begin
lInternalBindSourceAdapter := TObjectBindSourceAdapter<TMyObject>.Create(nil, TMyObject.Create, true);
lMyObject := lInternalBindSourceAdapter.Current as TMyObject;
LContext := TRttiContext.Create;
lRttiType := lContext.GetType(TMyObject);
lRttiProperties := lRttiType.GetProperties;
for lRttiProperty in lRttiProperties do
begin
lRttiProperty.Name;
Writeln(Format('TMyObject.%0:s -> lInternalBindSourceAdapter.FindField(''%0:s'') = %s'
, [lRttiProperty.Name, BoolToStr(GetMemberName(lInternalBindSourceAdapter.FindField(lRttiProperty.Name))<>'?', true)]));
end;
end;
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Запуск этой программы произведет это:
Выше следует отметить, что 'EnumField3' типа TMyEnum
не был успешно зарегистрирован TObjectBindSourceAdapter
.
Почему? Из-за этой реализации в модуле Data.Bind.ObjectScope.pas class procedure TBindSourceAdapter.AddPropertiesToList()