Mega Code Archive

 
Categories / Delphi / VCL
 

Enumerate all DB aware VCL components linked to a datasource

Title: Enumerate all DB-aware VCL components linked to a datasource Question: Often it is practical to enumerate all db-aware components that are connected to a particular datasource. In my case, I had to be able to automatically switch between Unicode and UTF-8 depending on the database engine. Answer: The following procedure will iterate through all db-aware components connected to a datasource, and call a user-defined callback method for each component found. UNIT enum_Dbaware; interface uses classes,db,dbctrls; Type tEnumerate_Db_Aware = procedure (component: tcomponent; fieldname:string; tds:tdataset; tso:tdatasource; fdl: tfielddatalink) OF OBJECT; Procedure Enumerate_Db_Aware (ds : tdatasource; enumerate : tEnumerate_DB_Aware); implementation // tweak to get at protected "datalinks" property Type tTweakDatasource=class(tdatasource) end; Procedure Enumerate_Db_Aware (ds : tdatasource; enumerate : tEnumerate_DB_Aware); var das : tdataset; t : tobject; fdl : tfielddatalink; fn : string; component : tcomponent; i : integer; begin das:=ds.dataset; for i:=0 to tTweakDataSource(ds).datalinks.count-1 do begin t:=tTweakDataSource(ds).datalinks[i]; if t IS tFielddatalink then begin fdl :=tfielddatalink(t); component :=fdl.control; fn :=fdl.fieldname; enumerate (component,fn,das,ds,fdl); end; end; end; end. //**************************************************************** Example: This code snippet will force all components of type tElWideDBEdit (Yes I use the "LMD Elpack" component suite) to use "UTF8" string format if the attached database field isn't a widestring Unicode field. UTF8 is a packed unicode format that can be stored in a normal Ansistring. This way, the form will support unicode on any database engine type. The "Afteropen" Event is the right place to call the procedure. procedure TMyForm.dataset1AfterOpen(DataSet: TDataSet); begin Enumerate_Db_Aware (datasource1, enumerate); end; procedure TMyForm.Enumerate(component: tcomponent; fieldname:string; tds:tdataset; tso:tdatasource; fdl: tfielddatalink); VAR field : tfield; begin field:=tds.fields.fieldbyname(fieldname); if component IS tElWideDBEdit then begin if (field IS tstringfield) and not (field is tWidestringfield) then tElWideDBEdit (component).UnicodeMode:=UMForceUtf8; end; end;