【问题标题】:How to get a list of all components on the Form at Design-Time?如何在设计时获取表单上所有组件的列表?
【发布时间】:2015-05-14 14:59:16
【问题描述】:

我需要在设计时获取表单上所有组件的列表(不是控件,只是组件)。

组件还必须在设计时作为 24x24 图像在表单上可见。

我可以使用这样的代码

procedure TForm2.GetComponentList(Memo1: TMemo)
var
  i: Integer;
begin
 for i := 0 to ComponentCount-1 do
   if (Components[i] is TComponent) and not (Components[i] is TControl) then
    Memo1.Lines.Add(Components[i].Name);
end;

但是在这里我会得到一些不可见的组件,比如 TField 等。

我只需要 IDE 在表单上显示为 24x24 位图的组件。

我可以使用 Open Tools API 吗?

【问题讨论】:

标签: delphi ide components design-time


【解决方案1】:

作为其他组件的一部分创建的非可视组件(例如 TDataSet 中的 TField 等)是包含组件的子组件。这种关系在 DFM 中很明显 - 如果将其视为文本,您将看到字段组件是相应数据集对象的子级。

直接放置在表单上的非可视组件(例如 TDataset 本身)是表单对象的子对象:

object frmMain: TfrmMain
  ...
  object MyClientDataSet: TClientDataSet
    ...
    object MyClientDataSetID: TIntegerField
      FieldName = 'id'
    end
    object MyClientDataSetTitle: TStringField
      FieldName = 'title'
      Size = 255
    end
  end
  object MyDataSource: TDataSource
    DataSet = MyClientDataSet
    Left = 488
    Top = 120
  end
end

即使非可视组件之间没有可视父/子关系,非可视组件也始终知道它们是否有父组件。

这可以通过 TComponentHasParent 属性访问。

然而,至关重要的是,Form被认为是直接放置的非可视组件的父级。

因此,如果 HasParent 对于表单上的非可视组件(Form.Components 中的项目)为 FALSE,那么它是直接放置的组件,而不是其他组件的子组件。

只需如下修改您的 if 条件:

if (NOT (Components[i] is TControl)) and (NOT Components[i].HasParent) then
  Memo1.Lines.Add(Components[i].Name);

请注意,我已经删除了对 is TComponent 的测试,因为对于 中的项目,这 总是 将是 TRUE Components 表单的属性。

【讨论】:

  • 我想问题是为什么问题中的代码不够。
  • 是的,我意识到我自己......表单始终拥有放置在其上的所有组件。我是如此接近答案(手指几乎合在一起)...... DFM 中的关系没有区别 - 对于视觉或非视觉,子组件有一个父组件。然而,有一个微妙的变化,这可以用来检测表单上的非可视“根”组件。我已经相应地修改了答案,并附上了建议的代码更改以达到预期的结果。
  • 现在好多了
猜你喜欢
  • 2013-04-29
  • 1970-01-01
  • 2021-04-19
  • 2016-11-01
  • 2013-06-15
  • 2018-09-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多