Editors: array of TDBComboBox; - >具体进行编辑所用的数据控件数组,动态生成 Labels: array of TLabel; - >各字段的标题,动态生成
---- 采用TDBComboBox优点是它不仅能具有一般的编辑功能,还能为各字段添加相应的提示信息。代码如下: { 为第I字段增加提示信息的方法} PRocedure TDBPanel.AddHits (ItemIndex: Integer; Hits: array of string); var m,n,i: Integer; begin n := Length(Editors); m := Length(Hits); if ItemIndex< n then begin for i:=0 to m-1 do Editors[ItemIndex].Items.Add(Hits[i]); end; end;
procedure Register; begin RegisterComponents('Additional', [TDBPanel]); end;
{ 为第I字段增加提示信息的方法} procedure TDBPanel.AddHits(ItemIndex: Integer; Hits: array of string); var m,n,i: Integer; begin n := Length(Editors); m := Length(Hits); if ItemIndex< n then begin for i:=0 to m-1 do Editors[ItemIndex].Items.Add(Hits[i]); end; end;
procedure TDBPanel.AKeyDown (Sender: TObject; var Key: Word; Shift: TShiftState); begin if (Sender is TDBComboBox) then begin case Key of VK_Next: (Sender as TDBComboBox) .DataSource.DataSet.Next; VK_PRIOR: (Sender as TDBComboBox) .DataSource.DataSet.Prior; end; end; end;
procedure TDBPanel.AKeyPress(Sender: TObject; var Key: Char); begin if (Sender is TDBComboBox) then begin if Key=#13 then (Owner as TForm).Perform(WM_NEXTDLGCTL, 0, 0); end; end;
procedure TDBPanel.ClearHits(ItemIndex: Integer); var n: Integer; begin n := Length(Editors); if ItemIndex< n then Editors[ItemIndex].Items.Clear; end;
{ 创建各字段的数据输入控件的方法} procedure TDBPanel.CreateEditors;// (DS: TDataSource; ColCount: Integer); var i, n, RowCount: Integer; TextHeight: Integer; begin if DataSource.DataSet.Active then begin n := DataSource.DataSet.FieldCount; { 计算最大的标题长度及显示长度} DataSource.DataSet.First; { 计算高度} TextHeight := Canvas.TextHeight(DataSource .DataSet.Fields[0].DisplayLabel) + FLineHeight; //10; { 计算行列数} RowCount := n div Columns; if n mod Columns < > 0 then inc(RowCount); { 分配内存} FreeEditors; SetLength(Editors, n); SetLength(Labels, n); { 创建滚动盒} FScrollBox := TScrollBox.Create(Owner); FScrollBox.Parent := Self; FScrollBox.Align := alClient; { 创建编辑} for i:=0 to n-1 do begin { 创建标题} Labels[i] := TLabel.Create(Owner); Labels[i].Parent := FScrollBox; //Self; Labels[i].Caption := DataSource.DataSet.Fields[i].DisplayLabel; Labels[i].Left := FLeft + (maxLabelLen + maxTextLen + 10) * (i div RowCount); Labels[i].Width := maxLabelLen; Labels[i].Top := FTop + (i mod RowCount) * TextHeight + 5; { 创建编辑对象} Editors[i] := TDBComboBox.Create(Owner); Editors[i].Parent := FScrollBox; //Self; Editors[i].Left := Labels[i].Left + Labels[i].Width; Editors[i].Width := maxTextLen; Editors[i].Top := FTop + (i mod RowCount) * TextHeight; Editors[i].DataSource := DataSource; Editors[i].DataField := DataSource.DataSet.Fields[i].FieldName; Editors[i].OnKeyPress := AKeyPress; Editors[i].OnKeyDown := AKeyDown; end; { 创建Ok按钮} OkButton := TButton.Create(Owner); OkButton.Parent := FScrollBox; OkButton.Left := Editors[n-1].Left; OkButton.Top := Editors[n-1].Top + TextHeight; OkButton.Caption := '确定'; OKButton.OnClick := FClick; end; end;
destructor TDBPanel.Destroy; begin FreeEditors; Inherited Destroy; end;
function TDBPanel.Editor(Index: Integer): TDBComboBox; begin if Index< Length(Editors) then Result := Editors[Index] else Result := nil; end;
procedure TDBPanel.FreeEditors; var i,n: Integer; begin { 内存的释放是要有顺序的!必须以创建的相反的顺序进行! 尤其是当组件之间有父子关系时} if OkButton< >nil then OkButton.Free; if Editors< >nil then begin n := Length(Editors); for i:=0 to n-1 do Editors[i].free; Editors := nil; n := Length(Labels); for i:=0 to n-1 do Labels[i].Free; Labels := nil; end; if FScrollBox< >nil then begin FScrollBox.Free; FScrollBox := nil; end; end;