Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>A long time ago I actually created my own Wizard for this, based on an actual Custom Form I wrote for a FrameWork of mine. When the Dialog for the wizard was shown, it would display all fields in a grid and allow the user to indicate which component should be used to display that field.</p> <p>In my case depending on the Type of field it was prefilled with specific components (eg a TcxDateEdit for a TDateTime field, ...). The user could still change that though, and indicate which fields he wanted to add to the form. Once the user closes the form it was just matter of itterating over all the fields and creating the corresponding control.</p> <p>Searched through my code and found this back :</p> <pre><code>{ Custom Devia Development Framework RecordView Module which adds functionality to create the DB Aware Controls for the RecordView } TDevFrameWorkRecordViewModule = class( TCustomModule ) protected procedure CreateDBAwareComponents( aParent : TComponent; aDataSource : TDataSource; aFields : TFields; aFieldDefs : TFieldDefs ); virtual; function DefaultWizardClass : TDBAwareControlWizardClass; virtual; function DefaultLabelClass : TComponentClass; virtual; function MaxFieldCaptionLength ( aFields : TFields ) : Integer; virtual; protected function GetSelectedComponents : IDesignerSelections; function GetSelectedControl : TControl; property SelectedControl : TControl read GetSelectedControl; property SelectedComponents : IDesignerSelections read GetSelectedComponents; public procedure DevAddDBAwareComponentsWizard( aParent : TControl ); virtual; procedure ExecuteVerb(Index: Integer); override; function GetVerb(Index: Integer): string; override; function GetVerbCount: Integer; override; end; ... procedure TDevFrameWorkRecordViewModule.CreateDBAwareComponents( aParent : TComponent; aDataSource : TDataSource; aFields : TFields; aFieldDefs : TFieldDefs ); var lcv : Integer; aLabel : TControl; aEdit : TWinControl; aDataBinding : TcxDBEditDataBinding; aTop , aLeft : Integer; aWidth : Integer; aMaxCaptionWidth: Integer; aDBLeft : Integer; aRecordView : IDevFrameWorkRecordView; aDBAwareClass : TComponentClass; aDBAwareVisible : Boolean; aWizardForm : TfrmDevFrameWorkAddDataAwareControlsWizard; begin { First make sure the procedure was triggered on a FrameWorkRecordView } if ( Supports( Root, IDevFrameWorkRecordView, aRecordView ) ) then begin { Now Create and Show the wizard so the user can specify all the options } aWizardForm := DefaultWizardClass.Create( Nil ); try aWizardForm.RecordDataSet := aRecordView.DataSource.DataSet; aWizardForm.InitialiseSettings; { If the user closed the Wizard using the OK button, we can continue the process } if ( aWizardForm.ShowModal = mrOK ) then begin { By default the label components should start at 8,8 in the Parent Container } aTop := 8; aLeft := 8; aWidth:= 121; aMaxCaptionWidth := MaxFieldCaptionLength( aFields ); { Now set the intial Left Position for our DBAware controls according to the MaxCaptionWidth } aDBLeft := 24 + ( ( ( aMaxCaptionWidth div 8 ) + 1 ) * 8 ); { Loop over all fields to create the Label and DBAwareComponent } for lcv := 0 to Pred( aFields.Count ) do begin { Get some settings from the Wizard form } aDBAwareClass := aWizardForm.GetDBAwareComponentClass( aFields[ lcv ] ); aDBAwareVisible := aWizardForm.GetDBAwareComponentVisible( aFields[ lcv ] ); { Only create the components if the user indicated he wants to see them } if aDBAwareVisible then begin { Now create the Label and the DBAware Control } aLabel := TControl ( Designer.CreateComponent( DefaultLabelClass, aParent, aLeft , aTop, aMaxCaptionWidth, 17 ) ); aEdit := TWinControl( Designer.CreateComponent( aDBAwareClass, aParent, aDBLeft, aTop, aWidth, 21 ) ); { Now Set the Label Properties } aLabel.Name := Designer.UniqueName( 'cxlbl' + aFields[ lcv ].FieldName ); aLabel.HelpType := htKeyWord; aLabel.HelpKeyword := Root.Name + '.' + aFields[ lcv ].FieldName; { Set the additional properties using RTTI } if ( IsPublishedProp( aLabel, 'FocusControl' ) ) then begin SetObjectProp( aLabel, 'FocusControl', aEdit ); end; if ( IsPublishedProp( aLabel, 'Caption' ) ) then begin SetStrProp( aLabel, 'Caption', aFields[ lcv ].DisplayLabel ); end; { Now set the Edit Properites } aEdit.Name := Designer.UniqueName( {'cxlbl' +} aFields[ lcv ].FieldName ); aEdit.HelpType := htKeyWord; aEdit.HelpKeyword := Root.Name + '.' + aFields[ lcv ].FieldName; { Set the additional properties using RTTI } if ( IsPublishedProp( aEdit, 'DataBinding' ) ) then begin aDataBinding := TcxDBEditDataBinding( GetObjectProp( aEdit, 'DataBinding' ) ); SetObjectProp( aDataBinding, 'DataSource', aDataSource ); SetStrProp ( aDataBinding, 'DataField' , aFields[ lcv ].FieldName ); end; if ( aEdit is TcxCustomDropDownEdit ) then begin aEdit.Width := aWidth + 16; end; { Now increment the Top position for the next control } inc( aTop, ( ( ( aEdit.Height div 8 ) + 1 ) * 8 ) ); end; end; end; finally FreeAndNil( aWizardForm ); end; end; end; function TDevFrameWorkRecordViewModule.DefaultLabelClass: TComponentClass; begin Result := TLabel; end; function TDevFrameWorkRecordViewModule.DefaultWizardClass: TDBAwareControlWizardClass; begin Result := TfrmDevFrameWorkAddDataAwareControlsWizard; end; procedure TDevFrameWorkRecordViewModule.ExecuteVerb(Index: Integer); var aSelections : IDesignerSelections; lcv : Integer; begin aSelections := TDesignerSelections.Create; Designer.GetSelections( aSelections ); for lcv := 0 to Pred( aSelections.Count ) do begin {$IFDEF CODESITE} csFWRecordView.Send( 'aSelection.Items[ lcv ]', aSelections.Items[ lcv ] ); {$ENDIF} end; Case Index of 0 : DevAddDBAwareComponentsWizard( SelectedControl ); else Inherited ExecuteVerb( Index ); end; end; {***************************************************************************** This function will be used to return a list of selected components on the current designer. @Name TDevFrameWorkRecordViewModule.GetSelectedComponents @author Devia - Stefaan Lesage @param None @return None @Exception None @See None ******************************************************************************} function TDevFrameWorkRecordViewModule.GetSelectedComponents: IDesignerSelections; begin Result := TDesignerSelections.Create; Designer.GetSelections( Result ); end; function TDevFrameWorkRecordViewModule.GetSelectedControl: TControl; var lcv : Integer; begin Result := Nil; if ( Assigned( SelectedComponents ) ) then begin if ( SelectedComponents.Count &lt;&gt; 0 ) then begin for lcv := 0 to Pred( SelectedComponents.Count ) do begin if ( SelectedComponents.Items[ lcv ] is TControl ) then begin Result := TControl( SelectedComponents.Items[ lcv ] ); Break; end; end; end; end; end; function TDevFrameWorkRecordViewModule.GetVerb(Index: Integer): string; begin Case Index of 0 : Result := 'Dev.AddDataAwareComponents'; end; end; function TDevFrameWorkRecordViewModule.GetVerbCount: Integer; begin Result := 1; end; {***************************************************************************** This function will determine the length of the Longest field's caption. @Name TDevFrameWorkRecordViewModule.MaxFieldCaptionLength @author Devia - Stefaan Lesage @param None @return Returns the length of the longest field's catpion. @Exception None @See None ******************************************************************************} function TDevFrameWorkRecordViewModule.MaxFieldCaptionLength( aFields: TFields): Integer; var aMaxCaptionWidth : Integer; aCanvas : TCanvas; lcv : Integer; aCaption : String; begin aMaxCaptionWidth := 0; { First Determine how long the largest caption will be } aCanvas := TDevFrameWorkRecordView( Root ).Canvas; { Loop over each field to dertermin which caption is the longest one } for lcv := 0 to Pred( aFields.Count ) do begin if ( aFields[ lcv ].DisplayLabel &lt;&gt; '' ) then begin aCaption := aFields[ lcv ].DisplayLabel; end else begin aCaption := aFields[ lcv ].FieldName; end; if ( aCanvas.TextWidth( aCaption ) &gt; aMaxCaptionWidth ) then begin aMaxCaptionWidth := aCanvas.TextWidth( aCaption ); end; end; { Return the Length of the Longest Caption } Result := aMaxCaptionWidth; end; procedure TDevFrameWorkRecordViewModule.DevAddDBAwareComponentsWizard( aParent : TControl ); var aRecordView : IDevFrameWorkRecordView; aDataSource : TDataSource; begin {$IFDEF CODESITE} csFWRecordView.EnterMethod( Self, 'DevAddDBAwareComponentsWizard' ); {$ENDIF} if ( Supports( Root, IDevFrameWorkRecordView, aRecordView ) ) then begin {$IFDEF CODESITE} csFWRecordView.SendMsg( csmInfo, 'Root supports I®FrameWorkRecordView' ); {$ENDIF} aDataSource := TDataSource( Designer.GetComponent( 'srcMain' ) ); if ( Assigned( aDataSource ) ) and ( Assigned( aDataSource.DataSet ) ) then begin {$IFDEF CODESITE} csFWRecordView.SendMsg( csmInfo, 'aRecordView.DataSource Assigned' ); csFWRecordView.SendMsg( csmInfo, 'aRecordView.DataSource.DataSet Assigned' ); {$ENDIF} CreateDBAwareComponents( aParent, aDataSource, aDataSource.DataSet.Fields, aDataSource.DataSet.FieldDefs ); end; end; {$IFDEF CODESITE} csFWRecordView.ExitMethod( Self, 'DevAddDBAwareComponentsWizard' ); {$ENDIF} end; </code></pre> <p>Of course this won't compile for you. It is something I wrote for a development framework in Delphi 7 a few years ago. It should give you an idea though on how you could actually do it.</p> <p>Regards,</p> <p>Stefaan</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload