刚搞定了遍历枚举类型的取值,又跌进集合类型的坑里了,资料查了好多,试来试去都不行,希望大侠帮助~~ function GetSetAllName(obj: TObject; PName: string): TStringList; var PropInfo: PPropInfo; PropType: PTypeInfo; TypeData: PTypeData; I: Integer; begin Result:=TStringList.Create; PropInfo := GetPropInfo(obj, PName); PropType := PropInfo.PropType^; TypeData := GetTypeData(PropType);
for I := TypeData.MinValue to TypeData.MaxValue do begin //Result.Add(GetEnumName(PropType, I)); 注释掉的这行是遍历枚举类型的 Result.Add(SetToString(PropInfo, I)); end;
Function TfxRttiPropertyItem.GetValueList:String; Var i :Integer; iList :TStringList; Begin iList :=TStringList.Create; Try if Assigned(FPropInfo) then Begin //有扩展的属性 if Assigned(FPropertyEditor) then Exit(TfxPropertyEditor(FPropertyEditor).GetValues); //无扩展的属性 case FPropInfo.PropType^.Kind of tkInteger,tkChar, tkWChar,tkFloat,tkString, tkLString, tkWString, tkUString,tkSet:Exit(''); tkEnumeration:Begin for I := FPropInfo.PropType^.TypeData.MinValue to FPropInfo.PropType^.TypeData.MaxValue do iList.Add(GetEnumName(FPropInfo.PropType^,I)); End; tkClass:Begin if GetTypeData(FPropInfo.PropType^)^.ClassType.InheritsFrom(TComponent) then Begin for I := 0 to FRunObj.ComponentCount - 1 do if FRunObj.Components[i] is GetTypeData(FPropInfo.PropType^)^.ClassType then iList.Add(FRunObj.Components[i].Name); if iList.Count=0 then iList.Add(''); End Else Exit(''); End; tkMethod:Begin Exit(''); End; End; End Else Begin iList.Add('False'); iList.Add('True'); End;
你是要获取集合的值还是集合枚举列表? Function TfxRttiPropertyItem.GetStrValue:String; Var SetInt : TIntegerSet; i :Integer; Ch : Char; Begin if Assigned(FPropInfo) then Begin case FPropInfo.PropType^.Kind of tkInteger: Exit(Inttostr(GetOrdProp(FParentObj,FPropInfo))); tkChar, tkWChar:Begin Ch := Chr(GetOrdProp(FParentObj,FPropInfo)); {$IFDEF Delphi12} if CharInSet(Ch, [#33..#255]) then {$ELSE} if Ch in [#33..#255] then {$ENDIF} Result := Ch else FmtStr(Result, '#%d', [Ord(Ch)]); End; tkFloat: //Exit(Floattostr(GetFloatProp(FParentObj,FPropInfo))); Exit(Floattostr(StrToFloat(FormatFloat('0.000000'{只保留六位数},GetFloatProp(FParentObj,FPropInfo))))); tkString, tkLString, tkWString, tkUString: Exit(GetStrProp(FParentObj,FPropInfo)); tkEnumeration: Exit(GetEnumName(FPropInfo.PropType^, GetOrdProp(FParentObj,FPropInfo))); tkSet:Begin Integer(SetInt) := GetOrdProp(FParentObj,FPropInfo); Result := '['; for i := GetTypeData(GetTypeData(FPropInfo.PropType^).CompType^)^.MinValue to GetTypeData(GetTypeData(FPropInfo.PropType^).CompType^)^.MaxValue do if i in SetInt then Begin if Length(Result) <> 1 then Result := Result + ','; Result := Result + GetEnumName(GetTypeData(FPropInfo.PropType^).CompType^, i); End; Result := Result + ']'; End; tkClass:Begin if GetTypeData(FPropInfo.PropType^)^.ClassType.InheritsFrom(TComponent) then Begin if Assigned(TComponent(GetOrdProp(FParentObj,FPropInfo))) then Exit(TComponent(GetOrdProp(FParentObj,FPropInfo)).Name) Else Exit(''); End Else if GetTypeData(FPropInfo.PropType^)^.ClassType.InheritsFrom(TPersistent) then Begin {$IFDEF NEXTGEN} Exit('TSymbolName'{'(' + String(FPropInfo.PropType^.Name) + ')'});//这里不知道怎么写,BYTE转STRING {$ELSE NEXTGEN} Exit('(' + String(FPropInfo.PropType^.Name) + ')'); {$ENDIF NEXTGEN} End; End; tkMethod:Begin Exit(''); End; End; End Else Begin//集合子元素 With TfxRttiPropertyList(Self.Collection).Parent do Integer(SetInt):=GetOrdProp(ParentObj,PropInfo); if Self.Index in SetInt then Exit('True'); Exit('False'); End; End; 应该是这个了
----------------------------------------------
就怕想不到,没有做不到的
感谢iamdream,感谢大家,问题已经搞定了 function GetSetAllName(obj: TObject; PName: string): TStringList; var PropInfo: PPropInfo; PropType: PTypeInfo; I: Integer; begin Result:=TStringList.Create; PropInfo := GetPropInfo(obj, PName); PropType := PropInfo.PropType^;
for i := GetTypeData(GetTypeData(PropType).CompType^)^.MinValue to GetTypeData(GetTypeData(PropType).CompType^)^.MaxValue do begin Result.Add(GetEnumName(GetTypeData(PropType).CompType^, i)); end;
function TForm1.GetEnumNames<T>: TArray<string>; var RTX: TRttiContext; RT: TRttiType; ROT: TRttiOrdinalType; I: Integer; LNames: TArray<string>; begin RT:= RTX.GetType(TypeInfo(T)); if RT.IsOrdinal then begin ROT:= RT.AsOrdinal; SetLength(Result, ROT.MaxValue + 1); for I:= ROT.MinValue to ROT.MaxValue do Result[I]:= System.TypInfo.GetEnumName(TypeInfo(T), I); end; end;
调用方法: type TTest = (tt01, tt02, tt03, tt04, tt05); var LNames: TArray<string>; begin LNames:= GetEnumNames<TTest>; //这里可以传任意枚举类型 end.
----------------------------------------------
虽千万人吾往矣!