问题描述
我有值存储在xml和lua代码中,并通过RTTI访问对象的属性。 var
o,v :电视// o是当前对象
a:TStringDynArray; // params as array
ctx:TRttiContext;
tt:TRttiType;
p:TRttiProperty;
pt:PTypeInfo;
begin
...
ctx:= TRttiContext.Create;
try
o:= GetLastClassInParams(ctx,obj,a,param_idx);
tt:= ctx.GetType(o.TypeInfo);
如果高(a)< param_idx then
raise Exception.Create(S_FN + S_NOP);
p:= tt.GetProperty(a [param_idx]);
如果p = nil then
raise Exception.Create(S_FN + S_PNE + a [param_idx]);
pt:= p.PropertyType.Handle;
case p.PropertyType.TypeKind of
tkInteger:v:= TValue.From< integer>(integer(Value));
tkEnumeration:v:= TValue.FromOrdinal(pt,GetEnumValue(pt,VarToStr(Value)));
tkUString:v:= TValue.From< string>(VarToStr(Value));
tkFloat:v:= TValue.From< double>(double(Value));
tkSet:begin
temp_int:= StringToSet(pt,VarToStr(Value));
TValue.Make(@temp_int,pt,v);
结束
else v:= TValue.FromVariant(Value);
结束
p.SetValue(o.AsObject,v);
我可以使用许多属性,如宽度
,TMemo等的 Lines.Text
,即使在TStatusBar(其中Panel是TCollection后代)的面板[0] .Width
),但是像 TStringGrid.Cells [x,y]
这样的东西是我无法解决的。
Embarcadero有一些帮助,还有一些功能,如 GetIndexedProperty
(也许这就是我需要的),但解释与一样好获得索引属性
。
如果我有值存储,如何在运行时通过RTTI设置并获取 TStringGrid.Cells [x,y]
像Cells[1,1]
?
以下是使用RTTI获取和设置字符串网格值的最简单的例子:
var
ctx:TRttiContext;
rttitype:TRttiType;
rttiprop:TRttiIndexedProperty;
值:TValue;
....
rttitype:= ctx.GetType(StringGrid1.ClassType);
rttiprop:= rttitype.GetIndexedProperty('Cells');
value:= rttiprop.GetValue(StringGrid1,[1,1]);
rttiprop.SetValue(StringGrid1,[1,1],value.ToString +'hello');
为了简单起见,我删除了错误检查。我会假设你已经知道如何检查错误。
I have values stored in xml and lua code and accessing object's properties through RTTI.
var
o, v: TValue; // o is current object
a: TStringDynArray; // params as array
ctx: TRttiContext;
tt: TRttiType;
p: TRttiProperty;
pt: PTypeInfo;
begin
...
ctx := TRttiContext.Create;
try
o := GetLastClassInParams(ctx, obj, a, param_idx);
tt := ctx.GetType(o.TypeInfo);
if high(a) < param_idx then
raise Exception.Create(S_FN + S_NOP);
p := tt.GetProperty(a[param_idx]);
if p = nil then
raise Exception.Create(S_FN + S_PNE + a[param_idx]);
pt := p.PropertyType.Handle;
case p.PropertyType.TypeKind of
tkInteger: v := TValue.From<integer>(integer(Value));
tkEnumeration: v := TValue.FromOrdinal(pt, GetEnumValue(pt, VarToStr(Value)));
tkUString: v := TValue.From<string>(VarToStr(Value));
tkFloat: v := TValue.From<double>(double(Value));
tkSet: begin
temp_int := StringToSet(pt, VarToStr(Value));
TValue.Make(@temp_int, pt, v);
end;
else v := TValue.FromVariant(Value);
end;
p.SetValue(o.AsObject, v);
I can work with many properties like Width
, Lines.Text
of TMemo etc, even with Panels[0].Width
of TStatusBar (where Panels is TCollection descendant), but thing like TStringGrid.Cells[x, y]
is something I can't solve.There is help on Embarcadero and some functions like GetIndexedProperty
(maybe that is what I need), but explanation there as good as "Gets Indexed Property"
.
How to set and get TStringGrid.Cells[x,y]
through RTTI at runtime if I have values stored as strings like "Cells[1,1]"
?
Here's the simplest example I can think off to get and set the values from a string grid using RTTI:
var
ctx: TRttiContext;
rttitype: TRttiType;
rttiprop: TRttiIndexedProperty;
value: TValue;
....
rttitype := ctx.GetType(StringGrid1.ClassType);
rttiprop := rttitype.GetIndexedProperty('Cells');
value := rttiprop.GetValue(StringGrid1, [1, 1]);
rttiprop.SetValue(StringGrid1, [1, 1], value.ToString + ' hello');
I excised the error checking for the sake of simplicity. I'm going to assume that you already know how to check for errors.
这篇关于如何通过RTTI设置/获取属性值,用于诸如TStringGrid.Cells之类的compex内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!