我正在使用 TObjectBindSourceAdapter
对对象使用实时绑定(bind)。
我与 TObjectBindSourceAdapter
一起使用的对象的属性之一具有枚举类型,但当我在对象中使用枚举类型时,适配器中的字段永远不会生成
我目前找到的唯一解决方案是将枚举类型定义为对象中的整数并对其进行类型转换。这似乎工作正常,但您必须保持枚举类型和整数的类型转换和返回。
这里有一些示例代码来解释我的意思。
第一个示例使用我最初尝试的枚举类型,但似乎不起作用:
uses Data.Bind.ObjectScope;
Type
TMyEnumtype = (meOne, meTwo, meThree);
TMyObject = class
public
MyEnumType: TMyEnumtype;
end;
procedure TForm9.But1Click(Sender: TObject);
var
MyObject: TMyObject;
aBindSourceAdapter: TBindSourceAdapter;
begin
MyObject := TMyObject.Create;
MyObject.MyEnumType := meTwo;
aBindSourceAdapter := TObjectBindSourceAdapter<TMyObject>.Create(nil, MyObject, False);
if aBindSourceAdapter.FindField('MyEnumType') <> nil then
ShowMessage('MyEnumType found')
else
showmessage('MyEnumType not found');
FreeAndNil(MyObject);
FreeAndNil(aBindSourceAdapter);
end;
第二个示例似乎通过类型转换为整数来工作
uses Data.Bind.ObjectScope;
Type
TMyEnumtype = (meOne, meTwo, meThree);
TMyObject = class
public
MyEnumType: integer;
end;
procedure TForm9.But1Click(Sender: TObject);
var
MyObject: TMyObject;
aBindSourceAdapter: TBindSourceAdapter;
aEnumType : TMyEnumtype;
begin
MyObject := TMyObject.Create;
MyObject.MyEnumType := Integer(meTwo);
aBindSourceAdapter := TObjectBindSourceAdapter<TMyObject>.Create(nil, MyObject, False);
if aBindSourceAdapter.FindField('MyEnumType') <> nil then
ShowMessage('MyEnumType found')
else
showmessage('MyEnumType not found');
aEnumType := TMyEnumtype(aBindSourceAdapter.FindField('MyEnumType').GetTValue.AsInteger);
if aEnumType = meTwo then
showmessage('meTwo');
FreeAndNil(MyObject);
FreeAndNil(aBindSourceAdapter);
end;
我想知道其他人是否遇到过这个问题,以及是否有其他解决方案可以解决这个问题,而无需恢复为整数并继续使用枚举类型。我也不确定我的解决方法是否是执行此操作的常用方法。
最佳答案
我认为最好的方法是注册转换器。事实证明这非常简单,但前提是要深入研究 VCL 源代码。我没有找到任何有用的文档。但它就在这里。
unit MyConverters;
interface
uses System.Rtti, System.Bindings.Outputs;
type
TMyEnum = (Value1, Value2, Value3);
implementation
procedure RegisterConverters;
begin
TValueRefConverterFactory.RegisterConversion(TypeInfo(TMyEnum), TypeInfo(string),
TConverterDescription.Create(
procedure(const InValue: TValue; var OutValue: TValue)
var
MyEnum: TMyEnum;
S: string;
begin
MyEnum := InValue.AsType<TMyEnum>;
case MyEnum of
Value1: S := 'First Value';
Value2: S := 'Second Value';
Value3: S := 'Third Value';
else S := 'Other';
end;
OutValue := TValue.From<string>(S);
end,
'TMyEnumToString',
'TMyEnumToString',
'', // TODO what is the AUnitName param used for?
True, // TODO what is ADefaultEnabled used for? What does it mean?
'Converts a TMyEnum value to a string',
nil)
);
end;
initialization
RegisterConverters;
end.
简而言之,您调用 TValueRefConverterFactor.RegisterConversion()
并传入:
- 此转换器转换的类型FROM
- 此转换器转换的类型TO
- 一个 TConverterDescription,其中包含一个实际执行转换的匿名过程以及一些其他元数据。
在上面的代码中,initialization
部分调用 RegisterConverters
,因此所需要做的就是在项目中包含该单元,实时绑定(bind)框架将使用转换器每当需要将 TMyEnum
值转换为 string
时。
关于delphi - 如何(正确)使用带有实时绑定(bind)的枚举类型(TObjectBindSourceAdapter),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16943387/