如何找出哪些DB-Aware控件链接到TDataSource? [英] How to find out which DB-Aware controls are linked to a TDataSource?
问题描述
我有 DataSource1(TDataSource)
,并且有一些链接到DB-Aware的控件(通过 SomeDBControl.DataSource = DataSource1
)
I have DataSource1 (TDataSource)
, and there are some DB-Aware controls linked to it (via SomeDBControl.DataSource=DataSource1
)
如何在代码中找出(枚举)哪些控件链接到给定的TDataSource?
How can I find out (enumerate) in code which controls are linked to a given TDataSource?
推荐答案
下面的代码使用RTTI,在D7中为我工作,它通过递归搜索容器对象(即表单及其内容)来列出具有DataSource或MasterSource属性的组件。
The code below, which uses RTTI, works for me in D7 to list the components which have a DataSource or MasterSource property by recursively searching a container object (i.e. the form and its components).
(显然,您可以对感兴趣的任何其他表单/数据模块执行类似的操作)
(Obviously, you could do similar for any other forms/datamodules you're interested in)
更新#1:该答案的原始版本生成了表单上每个组件的列表以及其DataSource / MasterSource的名称(如果有)。我已对其进行了更改,以使其与q正文中的要求更好地匹配。
Update #1: The original version of this answer produced a list of every component on a form and the name of its DataSource/MasterSource, if any. I've changed it to provide a better match with what you ask in the body of your q).
更新#2:在Update#1版本中进行了一些改动,并以一种避免在检查不具有DataSource / MasterSource属性的组件时避免生成异常的方式重新实现HasDataSource函数。
Update #2: This fixes a couple of slips in the Update #1 version, and re-implements the HasDataSource function in a way which avoids generating an exception when examining components which don't have a DataSource/MasterSource property.
function HasDataSource(AComponent : TComponent; var ADataSource : TDataSource) : Boolean;
function GetDataSource(APropName : String) : TDataSource;
var
AObject : TObject;
PInfo : PPropInfo;
begin
Result := Nil;
PInfo := GetPropInfo(AComponent, APropName);
if PInfo = Nil then
exit;
AObject := GetObjectProp(AComponent, PInfo);
Result := TDataSource(AObject);
end;
begin
Result := False;
ADataSource := GetDataSource('DataSource');
if ADataSource <> Nil then
Result := True;
if Result then exit;
ADataSource := GetDataSource('MasterSource');
if ADataSource <> Nil then
Result := True;
end;
procedure TForm1.Log(Msg: String);
begin
Memo1.Lines.Add(Msg);
end;
procedure TForm1.FindDataSourceObjects(AContainer : TComponent);
var
i : Integer;
ADataSource : TDataSource;
procedure LogDataSourceName(AContainer : TComponent);
begin
Log(AContainer.Name + ' Datasource: ' + ADataSource.Name);
end;
begin
if HasDataSource(AContainer, ADataSource) then
LogDataSourceName(AContainer);
for i := 0 to AContainer.ComponentCount - 1 do begin
FindDataSourceObjects(AContainer.Components[i]);
end;
end;
procedure TForm1.btnFindClick(Sender: TObject);
begin
FindDataSourceObjects(Self);
end;
我的表单的DFM是
object Form1: TForm1
Left = 195
Top = 124
Width = 623
Height = 303
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
PixelsPerInch = 96
TextHeight = 13
object DBText1: TDBText
Left = 307
Top = 56
Width = 65
Height = 17
DataSource = DataSource1
end
object Panel1: TPanel
Left = 307
Top = 80
Width = 281
Height = 161
Caption = 'Panel1'
TabOrder = 0
object DBText2: TDBText
Left = 24
Top = 64
Width = 65
Height = 17
DataSource = DataSource2
end
end
object Memo1: TMemo
Left = 8
Top = 16
Width = 281
Height = 225
TabOrder = 1
end
object btnFind: TButton
Left = 307
Top = 16
Width = 75
Height = 25
Caption = 'Find'
TabOrder = 2
OnClick = btnFindClick
end
object DataSource1: TDataSource
DataSet = ClientDataSet1
Left = 448
Top = 16
end
object DataSource2: TDataSource
DataSet = ClientDataSet2
Left = 544
Top = 16
end
object ClientDataSet1: TClientDataSet
Aggregates = <>
Params = <>
Left = 408
Top = 16
end
object ClientDataSet2: TClientDataSet
Aggregates = <>
MasterSource = DataSource1
PacketRecords = 0
Params = <>
Left = 496
Top = 16
end
end
这篇关于如何找出哪些DB-Aware控件链接到TDataSource?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!