gpt4 book ai didi

delphi - 发现链接到数据集字段的数据感知控件

转载 作者:行者123 更新时间:2023-12-03 15:51:24 24 4
gpt4 key购买 nike

在 Delphi 中,我应该如何获取链接到任何打开表单上的数据集字段的数据感知控件列表?

谢谢

最佳答案

以下内容基于我对此问题的回答:How to find out which DB-Aware controls are linked to a TDataSource?它询问如何查找链接到给定数据源的数据库感知控件。

它使用 TypInfo.Pas 中的传统 RTTI,因此可以虚拟地使用任何版本的德尔福。它不需要更新的 RTTI.Pas。下面的例子是在D7中编写和测试的。

到目前为止,这个答案还不太完整,因为

a) 它仅列出容器对象中的哪些组件(例如 Form 或 DataModule)以数据库感知方式链接到给定的数据集,但对其进行扩展查找哪些控件链接到数据集的特定字段;和

b) 它假设数据库感知控件遵循 Delphi 约定DataSource 字段,并且如果该控件是对特定字段进行操作的控件数据集(例如 TDBEdit,但不是 TDBGrid)、DataField 之一。

内联注释中解释了代码的工作原理;基本上,它迭代容器中的组件寻找数据源,然后检查它们是否是链接到给定的数据集,然后查找指定数据源的控件在其 DataSource 字段(如果有)中,并提取 DataField 的值属性(如果控件属于具有该属性的类型)。在明显的待办事项上是扩展代码以涵盖数据集和/或数据集的情况与数据库感知控件位于不同的容器(例如 DataModule)中。

示例项目包括一个TClientDataSet、TDataSource、TDBGrid和两个DBEdits 按照您期望的方式连接并生成输出

    DataSource: DataSource1 DataSet: ClientDataSet1
DBEdit1 (Classname: TDBEdit) is linked to ClientDataSet1
on datafield: ID
DBEdit2 (Classname: TDBEdit) is linked to ClientDataSet1
on datafield: Name

所以我希望很清楚它应该有能力,并且有更多功能工作,做你要求的事情。现在,我将其作为练习留给读者。

代码

  uses ... typinfo;

procedure TForm1.Log(Msg: String);
begin
Memo1.Lines.Add(Msg);
end;

function DataSourceHasDataSet(ADataSource : TDataSource; ADataSet : TDataSet) : Boolean;
begin
Result := ADataSource.DataSet = ADataSet;
end;

procedure TForm1.FindControlsForDataSet(AContainer : TComponent; ADataSet : TDataSet);
var
i, j : Integer;
ADataSource : TDataSource;
AComponent,
BComponent : TComponent;
AObject : TObject;
PInfo : PPropInfo;
AFieldName : String;

begin
// iterate the container looking for datasources
for i := 0 to AContainer.ComponentCount - 1 do begin
AComponent := AContainer.Components[i];
if AComponent is TDataSource then begin
ADataSource := TDataSource(AComponent);
// Check that ADataSource is linked to our specifiied dataset
if DataSourceHasDataSet(ADataSource, ADataSet) then begin
Log('DataSource: ' + ADataSource.Name + ' DataSet: ' + ADataSet.Name);

// now, iterate the container looking for controls which
// have a DataSource property specifying the found datasource
for j := 0 to AContainer.ComponentCount - 1 do begin
BComponent := AContainer.Components[j];
PInfo := GetPropInfo(BComponent, 'DataSource');
// PInfo will be non-NIL of the BComponent has a DataSource property
if PInfo <> Nil then begin
AObject := GetObjectProp(BComponent, PInfo);
if (AObject <> Nil) then
if (AObject is TDataSource) then begin
Log(BComponent.Name + ' (Classname: ' + BComponent.ClassName + ') is linked to ' + ADataSet.Name);
PInfo := GetPropInfo(BComponent, 'DataField');
if PInfo <> Nil then begin
AFieldName := GetStrProp(BComponent, 'DataField');
Log(' on datafield: ' + AFieldName);
end;
end;
end;
end;
end;
end;
end;
end;

procedure TForm1.btnFindClick(Sender: TObject);
begin
FindControlsForDataSet(Self, ClientDataSet1);
end;

由于感兴趣的项目可能分布在不同的表单/数据模块中,您可以使用 Screen 对象列出它们

  procedure TForm1.btnFormsClick(Sender: TObject);
var
i : Integer;
begin
for i := 0 to Screen.CustomFormCount - 1 do begin
Log(Screen.CustomForms[i].Name);
end;
for i := 0 to Screen.DataModuleCount - 1 do begin
Log(Screen.DataModules[i].Name);
end;
end;

关于delphi - 发现链接到数据集字段的数据感知控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54953288/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com