Jump to content
egnew

SetPropValue by Name

Recommended Posts

I can set the property of a component on a form by value:

SetPropValue(TopPanel,'align',alBottom);

 

I want to be able to set the property using the name of the value as a string:

SetPropValue(TopPanel,'align','alBottom');

 

How can this be accomplished?

 

Thanks

Share this post


Link to post

in fact, in RAD 11.3 "  SetPropValue(Button1, 'Align', 'alRight'); " works... because the "variant" is accepted and internally is used as "tkEnumeration:" type.

look at "procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);" in System.TypInfo.pas

---> SetEnumProp(Instance, PropInfo, VarToStr(Value))

--------> procedure SetEnumProp(Instance: TObject; PropInfo: PPropInfo;  const Value: string);  get the "name" of each value in TAlign and compare it.... if ok, result "Data := GetEnumValue(PropInfo^.PropType^, Value);"

 

------- edited ------

see "System.TypInfo.Set/GetVariantProp" + SetPropValue() usage!

https://docwiki.embarcadero.com/Libraries/Sydney/en/System.TypInfo.SetVariantProp

https://docwiki.embarcadero.com/Libraries/Sydney/en/System.TypInfo.GetVariantProp

 

or 

look this

https://stackoverflow.com/questions/45987321/change-component-properties-using-setpropvalue-and-rtti-with-delphi-tokyo

Edited by programmerdelphi2k

Share this post


Link to post

I checked the links you provided and do not yet see a solution.   I can just use SetPropValue when the property is a simple type of sting, integer, float, etc.  But here the property is a type.

 

I am using Align as an example type, as it is a property of all TControl components:

property Align: TAlign read FAlign write SetAlign default alNone;

I dynamically create components at runtime using text commands and set the values of the components from the text.  The command to create a panel aligned to TOP is "PANEL /ALIGN=TOP" which will be changed to "PANEL /ALIGN=alTOP" in the new version.  Once I have this working, I can set any property in a component without knowledge of the component.  In the current implementation, I have to deal with each property with a type using functions similar to this:

 

function SetAlign(p_Control: TControl; p_Value: String);

begin

    if SameText(p_Setting,'TOP') then

      p_Control.Align := alTop

    else if SameText(p_Setting,'BOTTOM') then

     p_Control.Align := alBottom

     etc...

end;

 

I validate a property name using this:
function GetPropertyType(p_Component: TComponent; const p_PropertyName: String): String;
var
  v_Context: TRttiContext;
  v_Property: TRttiProperty;
begin
  v_Property := v_Context.GetType(p_Component.ClassType).GetProperty(p_PropertyName);
  Result := v_Property.PropertyType.ToString;
end;

 

I am attempting to resolve these problems:

 

1)  How do I get the current value of the property?

 

2)  How do I change the value of a property when the property is a type?  That is the question posted here.

 

3)  How do I validate the string that identifies the new property value?

I can obtain valid strings for TAlign using the following:

for I := Ord(Low(TAlign)) to Ord(High(TAlign)) do
  p_Memo.Lines.Add(GetEnumName(TypeInfo(TAlign),I))

 

However, I have not been able to determine how to do this for a type I don't know ahead of time using a parameter like:

for I := Ord(Low(p_Type)) to Ord(High(p_Type)) do
  p_Memo.Lines.Add(GetEnumName(TypeInfo(p_Type),I))

 

Thanks

 

 

 

Share this post


Link to post

1)     var LVal : variant := GetPropValue(Panel1, 'Align'); // get it value

 

2)  will be this?  {case}    if VarType( LVal ) = varUString { varString, etc... } then   SetPropValue(Button1, 'Align',   string( LVal )  );
 

 

Project1_oWLgxWzlBe.gif

Edited by programmerdelphi2k

Share this post


Link to post

Thanks very much.

 

1 - Works Perfectly

2 - Works Perfectly

3 -  Any idea how to the names of the type values?  I can do it as shown in my previous email by specifying the type.  I need to do it from the type name instead.

 

4 - I used this code to get the property type.  Is there a better way?

 

function GetPropertyType(p_Component: TComponent; const p_PropertyName: String): String;
var
  v_Context: TRttiContext;
  v_Property: TRttiProperty;
begin
  v_Property := v_Context.GetType(p_Component.ClassType).GetProperty(p_PropertyName);
  Result := v_Property.PropertyType.ToString;
end;

 

Thanks

Share this post


Link to post

3)  Not a problem.  I realized I didn't need the list of values.  I can try the provided value.  An "invalid property element: <value>" exception is returned.

 

However, if you have a solution, that would be useful.

 

Thanks again.

Share this post


Link to post

Maybe this helps you as it helped me.

That method looks if property is available and set it.

uses
  TypInfo, Rtti;

function SetProperty(const AControl: TControl; const AProperty: string; const AValue: TValue): Boolean;
var
  LControl: TControl;
  LRttiContext: TRttiContext;
  LRttiProperty: TRttiProperty;
begin
  Result := False;
  try
    LControl := AControl;
    LRttiProperty := LRttiContext.GetType(LControl.ClassType).GetProperty(AProperty);
    if ((LRttiProperty <> nil) and (LRttiProperty.Visibility in [mvPrivate, mvProtected, mvPublic, mvPublished])) then
    begin
      LRttiProperty.SetValue(LControl, AValue);
      Result := True;
    end;
  except
  end;
end;

and it can be used like:

SetProperty(AControl, 'Caption', AValue);

 

  • Thanks 1

Share this post


Link to post

KodeZwerg.

I had a solution using just System.TypInfo, which works for all simple types.

try
    SetPropValue(p_Component,p_PropertyName,p_PropertyValue);
except
...

But your version is better as it allows me to set all properties.

Example:  SetPropertyValue(TControl(MyFDConnection.Params),'UserName','MyUserName');

 

Thank you very much.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×