向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 |


浙公网安备 33010602011771号