+ -
当前位置:首页 → 问答吧 → 动态生成组件,窗体如何调用数据模块里的组件

动态生成组件,窗体如何调用数据模块里的组件

时间:2011-11-15

来源:互联网

可能我描述的不是很准确:数据模块里根据需要自动生成数据连接组件,并返回数据连接组件的名称,FORM里调用数据模块里的方法,得到数据连接组件的名称,该怎么引用呢?

数据模块

unit MYData;

interface

uses
  SysUtils, Classes, WideStrings, DbxDatasnap, DB, DBClient, SqlExpr, DSConnect,
  DBXCommon, DBAccess, Uni, IndyPeerImpl, Data.FMTBcd, Datasnap.Provider,Generics.Collections;

type
  TMYDB = class(TDataModule)
  DBConn: TSQLConnection;
  cds: TClientDataSet;
  DS: TDataSource;
  DSPCon: TDSProviderConnection;
  type
  TDBLink = record
  CDS: string;
  DS: string;
  DSPCon: string;
  end;
  procedure DataModuleCreate(Sender: TObject);
  private
  { Private declarations }

  ListofCDS : TDictionary<Integer,TClientDataSet>;
  ListofDSPCon : TDictionary<Integer,TDSProviderConnection>;
  ListofDS : TDictionary<Integer,TDataSource>;

  function _CreatDataSource:TDBLink;
  public
  { Public declarations }
  function GetDataObjNumber: integer;
  function GetDBLink:TDBLink;

  //procedure CloseQuery(sdbprv :string);
  end;

var
  MYDB: TMYDB;


implementation

{$R *.dfm}

uses ClientPublic;

procedure TMYDB.DataModuleCreate(Sender: TObject);
begin
  ListofCDS := TDictionary<Integer,TClientDataSet>.Create;
  ListofDSPCon := TDictionary<Integer,TDSProviderConnection>.Create;
  ListofDS := TDictionary<Integer,TDataSource>.Create;
end;

function TMYDB._CreatDataSource:TDBLink;//根据需求,自动生成数据连接组件,并返回组件的名称
var
  I: Integer;
  MyDBLink : TDBLink;
begin
  Result := 0;

  try
  for I := 1 to CMAX_PoolSize do
  begin
  if ListofCDS.ContainsKey(I) then //判断池子对象是否存在
  begin
  if ListofCDS[i].State=dsInactive then //池子对象是否空闲
  begin
  MyDBLink.CDS:=ListofCDS[I].Name;
  MyDBLink.DS := ListofDS[I].Name;
  MyDBLink.DSPCon := ListofDSPCon[I].Name;
  Result:=MyDBLink;

  Break;
  end;
  end
  else
  begin //池子未满,创建对象

  MyDBLink.CDS:= TClientDataSet.Create(Self);
  MyDBLink.DS := TDataSource.Create(Self);
  MyDBLink.DSPCon:= TDSProviderConnection.Create(Self);

  MyDBLink.CDS:=CDS_Prv + IntToStr(I);
  MyDBLink.DS := DS_Prv + IntToStr(I);
  MyDBLink.DSPCon := DSPCON_Prv + IntToStr(I);


  ListofCDS.Add(I, MyDBLink.CDS);
  ListofDS.Add(I, MyDBLink.DS);
  ListofDSPCon.Add(I, MyDBLink.DSPCon);

  ListofDSPCon[I].ServerClassName:='TSCErp_ServerMethods';
  ListofDSPCon[I].SQLConnection:=DBConn;
  ListofCDS[I].RemoteServer:=ListofDSPCon[I];
  ListofDS[I].DataSet:=ListofCDS[I];
  Result:=MyDBLink;
  break;
  end;
  end;
  finally

  end;

end;



function TMYDB.GetDBLink:TDBLink;//窗体调用该方法,获取组件的名称
begin
  Result :=_CreatDataSource;
end;

end.



窗体里调用
procedure TForm3.menu_lockClick(Sender: TObject);
type
  TDBLink = record
  CDS: string;
  DS: string;
  DSPCon: string;
end;
var
  Server: TSCErp_ServerMethodsClient;
  MyDBLink : TDBLink;
  ObjNum:Integer;
  CDS_name:string;
  DS_name:string;
  DSPCon_name:string;
begin
  //cxGrid1
  MyDBLink:=MYDB.GetDBLink;//调用数据模块里的方法,获取组件名称

  dbview.DataController.DataSource:=MYDB.(MyDBLink.DS);//这里该怎么写//这里该怎么写//这里该怎么写

  Server := TSCErp_ServerMethodsClient.Create(MYDB.DBConn.DBXConnection);
  try
  MYDB.(FindComponent(MyDBLink.DSPCon) as Tdatasetprovider).providername
  MyDBLink.CDS.ProviderName:=Server.GetProviderName;
  MYDB.cds.Open;
  ShowMessage(MYDB.cds.ProviderName);
  finally
  Server.Free
  end;
end;

作者: bruin74   发布时间: 2011-11-15

这样做是为了不在数据模块创建N多的数据连接组件!

作者: bruin74   发布时间: 2011-11-15

Const

  //定义池子大小
  CMAX_PoolSize =5;
  CDS_Prv ='CDS';
  DS_Prv ='DS';
  DSPCON_Prv ='DSPCon';

作者: bruin74   发布时间: 2011-11-15

强制转换,其它組件,同理
dbview.DataController.DataSource:=TDataSource(MYDB.(MyDBLink.DS));

dbview.DataController.DataSource:=(MYDB.(MyDBLink.DS) AS TDataSource);

作者: kaikai_kk   发布时间: 2011-11-15

引用 3 楼 kaikai_kk 的回复:

强制转换,其它組件,同理
dbview.DataController.DataSource:=TDataSource(MYDB.(MyDBLink.DS));

dbview.DataController.DataSource:=(MYDB.(MyDBLink.DS) AS TDataSource);
这样没用的

作者: bruin74   发布时间: 2011-11-15