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;