【问题标题】:Dynamically access a property in a Delphi component动态访问 Delphi 组件中的属性
【发布时间】:2011-01-05 11:42:48
【问题描述】:

我使用的是 Delphi 5,我们有一种方法可以根据数据库表的内容动态创建某些控件(我们主要创建 TButtons)并在单击这些控件时执行操作。这允许我们在表单中添加简单的控件,而无需重新编译应用程序。

我想知道是否可以根据字符串中包含的属性名称设置组件的属性,以便我们可以设置更多选项。

伪代码:

Comp := TButton.Create(Self);

// Something like this:
Comp.GetProperty('Left').AsInteger := 100;
// Or this:
Comp.SetProperty('Left', 100);

这可能吗?

【问题讨论】:

  • 请注意,配置中的格式错误的内容可能会导致您进入有趣的故障模式。 (去过那里,做到了。)

标签: delphi dynamic


【解决方案1】:

您必须使用 Delphi 的 运行时类型信息 功能来执行此操作:

此博客准确地描述了您正在尝试做的事情:Run-Time Type Information In Delphi - Can It Do Anything For You?

基本上你要获取属性信息,使用GetPropInfo,然后使用SetOrdProp设置值。

uses TypInfo;

var
  PropInfo: PPropInfo;
begin
  PropInfo := GetPropInfo(Comp.ClassInfo, 'Left');
  if Assigned(PropInfo) then
    SetOrdProp(Comp, PropInfo, 100);
end;

这不像您的伪代码那样简洁,但它仍然可以完成工作。此外,它与其他东西一起变得更加复杂,比如数组属性。

【讨论】:

  • 太棒了,我现在正在解析字符串、实例化控件并动态设置属性!
【解决方案2】:

来自我的一个工作单位(尽管在 Delphi 7 中)

  var
     c : TComponent;

  for i := 0 to pgcProjectEdits.Pages[iPage].ControlCount - 1 do
  begin
     c := pgcProjectEdits.Pages[iPage].Controls[i];
     if c is TWinControl
     then begin
        if IsPublishedProp(c,'color')
        then
           SetPropValue(c,'color',clr);
        if IsPublishedProp(c,'readonly')                        
        then                                                    
           SetPropValue(c,'readonly', bReadOnly );  
        ...            
     end;
     ...

您必须在使用语句中包含TypInfo。 不知道这是否适用于 Delphi 5。

【讨论】:

  • 啊,IsPublishedProp() 比上面的要好得多,我在我的代码中使用了两者的组合。非常感谢。
【解决方案3】:

作为一个附加的例子。下面是如何设置子属性,我在这个 Button 组件上设置 Margins:

uses TypInfo;

...

procedure TForm1.Button1Click(Sender: TObject);
begin
  var PropInfo := GetPropInfo(Button1.ClassInfo, 'Margins');
  if Assigned(PropInfo) then
  begin
    var Margins := TMargins.Create(self);
    try
      Margins.Left := 100;
      Margins.Top := 100;
      Margins.Right := 100;
      Margins.Bottom := 100;
      SetObjectProp(Button1, PropInfo, Margins);
    finally
      Margins.Free;
    end;
  end;
end;

由于内联变量,这适用于 Delphi 10.3 Rio 及更高版本。

【讨论】:

    猜你喜欢
    • 2016-08-06
    • 2017-05-20
    • 2019-06-15
    • 2021-08-01
    • 2020-11-21
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 2013-07-12
    相关资源
    最近更新 更多