新文章 网摘 文章 随笔 日记

向DBGrid添加按钮

DBGrid非常方便,并为大多数任务提供了方便的界面。但是您可能会发现,当您尝试实现某些风吹草动时,它就不够用了。例如,向网格中添加诸如SpeedButtons或SpinButtons之类的组件确实可以为应用程序增添趣味。但是你怎么做呢?Steve Zimmelman提供了一种简单的技术。

要将按钮添加到DBGrid,您确实需要一个更灵活的DBGrid。因此,第一步是对TDBGrid进行子类化,并公开其某些方法和属性(请参见后面的代码块)。为了将按钮放置在正确的单元格坐标中,您需要知道当前行以及正在显示的单元格的CellRect。在使用它时,您可以在DefaultRowHeight属性周围放置一个包装器,以便更改网格的行高,以获得更舒适的外观。

用于显示按钮的关键事件是OnDrawColumnCell。但是事件的参数Rect(TRect的一种)并不总是能够正常满足您的需求。这是因为Rect是要绘制的单元格,并且您需要由Row属性标识的数据单元格。

unit DBGridObj;
  interface

  uses Windows, Messages, SysUtils, Classes, Graphics,
       Controls, Forms,Grids, dbGrids;

 Type
  TDBGridObj = class(TDBGrid)

  Private
    FRowHeight : Integer ;
    Protected
    Procedure
    SetRowHeight(Value:Integer);
  Public
    // The inherited method is declared as protected.
    // Used Reintroduce to hide compiler warnings.
    Function CellRect(ACol,Arow : Longint):TRect; Reintroduce;

    // Expose Row and Col properties
    Property Row ;
    Property Col ;
  Published
    Property RowHeight : Integer
       Read FRowHeight Write SetRowHeight ;
  End;

procedure Register;

implementation
  Uses DB ;

Function TDBGridObj.CellRect(ACol,ARow:Longint):TRect;
Begin
   Result := Inherited CellRect(ACol, ARow);
End;

Procedure TDBGridObj.SetRowHeight(Value:Integer);
Begin
   If FRowHeight <> Value Then Begin
      FRowHeight := Value ;
      DefaultRowHeight := FRowHeight ;
      // Force Grid to update the RowCount.
      // The method I need to call is
      // UpdateRowCount, but it's declared
      // as private in the parent.  This
      // calls it by making the grid think it has
      // been resized.
      If Self.DataLink.Active Then Begin
         Perform(WM_SIZE,0,0);
     End;
   End;
End;

procedure Register;
Begin
   RegisterComponents('Custom', [TDBGridObj]);
End;

End.

现在您有了一个可以满足您的需求的DBGrid,您可以向其中添加一些按钮。

将新的TDBGridObj放在窗体上并创建一个OnDrawColumnCell事件。将SpeedButton放在表单上的任何位置。

以下代码很粗糙,您可能不希望在应用程序中完全按原样使用它,但是它提供了一个很好的示例,说明如何将它们组合在一起。

我使用Column参数的Index属性来标识要在其中放置按钮的Column。通过基于“当前数据单元格的Rect”的一些简单计算即可获得按钮的位置。

 

procedure TForm1.DBGridObj1DrawColumnCell(Sender: TObject; const Rect: TRect;
                                          DataCol: Integer; Column: TColumn;
                                          State: TGridDrawState);
Var DataRect : TRect ;
Begin
   // Place the button in the first column.
   If (Column.Index = 0) Then Begin
      With ButtonDBGrid1 Do Begin
         DataRect := CellRect(Column.Index,Row);
      End;
   // Assign the button's parent to the grid.
   If SpeedButton1.Parent <> ButtonDBGrid1 Then
      SpeedButton1.Parent := ButtonDBGrid1 ;
   // Set the button's coordinates.
   // In this case, right justify the button.
   If SpeedButton1.Left <> (DataRect.Right - SpeedButton1.Width) Then
      SpeedButton1.Left := (DataRect.Right - SpeedButton1.Width) ;
   If (SpeedButton1.Top <> DataRect.Top) Then
      SpeedButton1.Top := DataRect.Top ;

   // Make sure the button's height fits in row.
   If (SpeedButton1.Height <> (DataRect.Bottom-DataRect.Top)) Then
      SpeedButton1.Height := (DataRect.Bottom-DataRect.Top);

   End;
End;

这就是全部!可以以相同的方式使用TSpinButtons,但有一个例外:将SpinButton的Ctl3D属性设置为False。否则,它会在单元格的顶部和底部留下黑色边框。

使用此方法,您的网格可以如下所示:

您可以将其用作蓝图,但是更完整的方法是使用TCollection和TCollectionItem封装按钮。本文的下载文件包含一个TCollection示例。

Steve Zimmelman是马萨诸塞州波士顿地区的SK Zimmelman&Associates,Inc.总裁,还是Pinnacle Publishing的FoxTalk通讯和《 InfoWorld》杂志的撰稿人。他还弹奏着出色的布鲁斯吉他。电子邮件: solutions@skzimmelman.com  网站:www.skzimmelman.com

 

http://skzimmelman.com/Articles/buttongrid.htm

posted @ 2021-02-06 09:34  岭南春  阅读(727)  评论(0)    收藏  举报