There are many situations where you have a dataset with unknown fields structure or you just want to popup a small form and present to user some specific fields from the dataset , ie the fields need to be edited after an unsuccessful validation.
So, here is a simple function i have been using for long time ago to create data aware controls on panels, dialogs, scrollboxes:
Have fun developing, because development is fun!
So, here is a simple function i have been using for long time ago to create data aware controls on panels, dialogs, scrollboxes:
uses StdCtrls, DB, DbCtrls, TypInfo; var Label_W: integer = 200; {@ Width of the label controls} Control_W: integer = 500; {@ Max width of edit controls} Ctrl_Ident: integer = 2; {@ Distance between controls (horz & vert)} function CreateDatasetEditor( COwner: TComponent; {@ The owner of control, it will be responsible for destruction} WParent: TWinControl; {@ The parent window where controls will live in} DSource: TDataSource; {@ TDataSource to be associated with controls} const Names, {@ Array of field names to use (optional, empty array will use all fields from TDataSource.Dataset} Labels: array of string; {@ Array of labels to use (optional, empty cells will use field.DisplayLabel } X: integer; Y: integer {X,Y coordinates in WParent to start positioning controls} ): TRect; {@ Result TRect used to place controls} var i, j, iHigh: integer; c, ic : TControl; s: string; fld: TField; iL,iT: integer; Fields: TFields; Canvas: TControlCanvas; {@ Create a label control} procedure CreateDBLabel(ForField: TField; LabelText: string); begin with TLabel.Create(COwner) do begin Parent := WParent; AutoSize := False; Left := iL + Ctrl_Ident; Inc(iT,Ctrl_Ident); Top:=iT; Width := Label_W; WordWrap := False; if LabelText<>'' then Caption := LabelText else Caption := ForField.DisplayLabel; Alignment := taRightJustify; AutoSize := True; Transparent := True; end; end; {@ Create editing data aware control} function CreateEditField(ForFld: TField; sLabel: string): TControl; var w, h: integer; begin {@ Create edit control's associated label} CreateDBLabel(ForFld, sLabel); {@ Create actual data aware control based on filed info} if (ForFld.DataType in [ftBoolean]) then begin Result := TDBCheckBox.Create(nil); end else if (ForFld.DataType in [ftMemo, ftFmtMemo]) then begin Result := TDBMemo.Create(nil); Result.Width := Control_W; end else if (ForFld.FieldKind = fkLookup) then begin Result := TDBLookupComboBox.Create(nil); end else begin Result := TDBEdit.Create(nil); end; {@ Insert created control to COwner component hierarchy (for destruction puproses)} COwner.InsertComponent(Result); {@ Set control parent, width and other properties} Canvas.Control := Result; Result.Parent := WParent; Result.Enabled := not ForFld.ReadOnly; case ForFld.DataType of ftWord, ftSmallInt, ftInteger, ftAutoInc, ftLargeint: w := Canvas.TextWidth('###,###,###,###,###')+25; ftCurrency, ftFloat: w := Canvas.TextWidth('###,###,###,###,##0.00')+25; else w := ForFld.DisplayWidth * Canvas.TextWidth('W')+50; h := Canvas.TextWidth('Wq')+3; end; if not (ForFld.DataType in [ftMemo, ftFmtMemo]) then if w > Control_W then Result.Width := Control_W else Result.Width := w; {@ Connect control to DataSource & Field} TypInfo.SetOrdProp(Result,'DataSource',LongInt(DSource)); TypInfo.SetPropValue(Result,'DataField',ForFld.FieldName); {@ Final adjustment of control width} if Result.Width > Control_W then Result.Width := Control_W; end; {@ Position a control in sequence} procedure PositControl(c: TControl); begin c.Left := iL + Ctrl_Ident*2 +Label_W; c.Top:=iT; Inc(iT,c.Height); Result.Bottom := iT; if Result.Right < c.BoundsRect.Right then Result.Right := c.BoundsRect.Right; end; begin if not Assigned(DSource.DataSet) then Exit; Fields := DSource.DataSet.Fields; iL:=X;iT:=Y; Result.Left := X; Result.Top := Y; Canvas := TControlCanvas.Create; try iHigh := High(Labels); if Length(Names) > 0 then begin // Create controls from Names array j:=High(Names); for i:=0 to j do begin fld := Fields.FindField(Names[i]); if Assigned(Fld) then begin s:=''; if (i<=iHigh) then s := Labels[i]; c := CreateEditField(Fld,s); if Assigned(c) then PositControl(c); end; end; end else begin //Create controls from dataset.fields j:=Fields.Count-1; for i:=0 to j do begin s:=''; if (i<=iHigh) then s := Labels[i]; c := CreateEditField(Fields[i],s); if Assigned(c) then PositControl(c); end; end; finally Canvas.Free; end; end;
Have fun developing, because development is fun!
No comments:
Post a Comment