Mega Code Archive

 
Categories / Delphi / ADO Database
 

Getting the controls used by fields

Title: Getting the controls used by fields Question: How to know what controls are used to edit the fields in a dataset linked with a datasource? Answer: ................................................................................ Getting the controls used by fields by Rubem Nascimento da Rocha - cartouche@ig.com.br Manaus, AM - Brazil (2002 August) (Check it out the sample project inside Sample.zip) ................................................................................ The data aware VCL has a very interesting feature to ensure separate bussiness logic from visual interface. When we're working with data-aware controls and dataset components, we can force the focus to a specific field using then FocusControl TField's method. However, in some cases, this is not enough. Even if this method was called from a data module, sometimes the focus is not directed to the control used to edit the field (e.g., a TDBGrid). I've noted this a long time ago, and then I've created a very good function to use on my dataset maintenance forms, and others where it's applicable, to find what control is used to edit a specific field in a dataset linked with a datasource. With the function source code, you can extend this idea to, for instance, write functions to control all the controls used by a datasource and set the focus to the exact control used by a specific field. I hope you enjoy it! []s //---------------------------------------------------------------------------- // GetControlField - Given a window control (TForm, TPanel, etc.), a data // source (TDataSource) and a field name, this function will try to find and // return which control is used to edit the field contents, even a grid. // // by Rubem Nascimento da Rocha (Manaus-AM/Brazil) - cartouche@ig.com.br //---------------------------------------------------------------------------- type THackDBGrid = class(TCustomDBGrid); function GetControlField(AOwner: TWinControl; ADataSource: TDataSource; ADataField: String): TWinControl; const PropDataSource = 'DataSource'; PropDataField = 'DataField'; var I: Integer; Found: Boolean; RefWinControl: TWinControl; CurrControl: TControl; PropInfo: PPropInfo; PropValue: String; Stack: TStringList; // recurse engine AuxObject: TObject; function GridHasField: Boolean; var _Field, _Qty: Integer; _AName: String; begin Result := False; with THackDBGrid(CurrControl) do begin _Qty := DataLink.FieldCount; for _Field := 0 to _Qty - 1 do begin _AName := UpperCase(DataLink.Fields[_Field].FieldName); Result := (_AName = UpperCase(ADataField)); if Result then Break; end; end; end; begin Found := False; RefWinControl := AOwner; I := Pred(RefWinControl.ControlCount); Result := NIL; Stack := TStringList.Create; try while ((I = 0) or (Stack.Count 0)) and (not Found) do begin // Check if control will be only checked checado or if all your // child controls, one-by-one, will do CurrControl := RefWinControl.Controls[I]; if CurrControl is TWinControl then if TWinControl(CurrControl).ControlCount 0 then begin Stack.AddObject(IntToStr(I), RefWinControl); RefWinControl := TWinControl(CurrControl); I := Pred(RefWinControl.ControlCount); Continue; end; PropInfo := GetPropInfo(CurrControl.ClassInfo, PropDataSource); if Assigned(PropInfo) then begin AuxObject := TObject(GetOrdProp(CurrControl, PropInfo)); // check if control is a data-aware grid if CurrControl is TCustomDBGrid then Found := GridHasField else begin PropInfo := GetPropInfo(PTypeInfo(CurrControl.ClassInfo), PropDataField); if Assigned(PropInfo) then begin // ... check if property has the search value PropValue := GetStrProp(CurrControl, PropInfo); Found := (TDataSource(AuxObject) = ADataSource) and (UpperCase(PropValue) = UpperCase(ADataField)); end; end; end; while (Pred(I) = -1) and (Stack.Count 0) do begin I := StrToInt(Stack[Pred(Stack.Count)]); RefWinControl := TWinControl(Stack.Objects[Pred(Stack.Count)]); Stack.Delete(Pred(Stack.Count)); end; Dec(I); if Found then result := TWinControl(CurrControl); end; finally Stack.Free; end; end; //----------------------------------------------------------------------------