You have the ability to change the appearance of your DBGrids. This is accomplished by drawing the cells' canvas of the grid yourself. At first, this may seem like a lot of work. But don't worry, we'll step through an example.
The DefaultDrawing property of the DBGrid determines if the cell is painted and the item it contains is drawn automatically. If True, the default drawing occurs. If False, your application must handle all the drawing details in the OnDrawCell event handler, or in the OnDrawDataCell event handler for the data grid. In this example, we will set the DefaultDrawing property to False and specify the code within the OnDrawDataCell event.
The OnDrawDataCell event occurs whenever the contents of a data grid cell needs to be redisplayed. For example, it occurs when the user selects a cell or scrolls the grid.
Let's get going and add some colors to your DBGrid !!!
Note: This example assumes you have an DBDEMOS alias pointed to the sample
database files located in \DELPHI\DEMOS\DATA
1. Create a New Project. ( File | New Project )
2. Save the Project.
3. Save the unit as STOCKGRD.PAS and the project as STKFOLIO.DPR
4. With Form1
- Set the Name Property to 'MyStockForm'
- Set the BorderStyle to bsSingle
- Add a public declaration to the TMyStockForm
Added code:
public
{ Public declarations }
AlertAmount: Double;
5. Set the Caption Property of MyStockForm to 'My Stock Portfolio'
6. Add a TPanel component on your form
7. With Panel1 do
- Clear the Caption Property
- Set the Align Property to alClient
- Set the BevelInner Property to bvLowered
- Set the BevelOuter Property to bvRaised
- Set the BevelWidth Property to 2
- Set the BorderWidth Poperty to 1
8. Add a TTable, TDataSource, and TDBGrid to the form
9. With Table1 do
- Set the DatabaseName Property to DBDEMOS
- Set the IndexFieldNames to SYMBOL
- Set the TableName to HOLDINGS.DBF
10. Select the Table component on the form and double-click it
(Bring up the Fields Editor)
With the Fields Editor
- Click the Add.. button, select and add all fields except
for ACCT_NBR and then click OK
- Click the Define.. button and define a new calculated field
from the Define Field Dialog. Name the field CURRENT_VAL
and set the Field Type to a StringField.
11. Select the Table Component and set the Active Property to True
12. Select the Table component on the form and edit the
OnCalcFields Event.
OnCalcFields Event Code:
---------------------------------------------------------------
procedure TMyStockForm.Table1CalcFields(DataSet: TDataset);
var
z: Double;
begin
z:=Table1PUR_PRICE.Value * Table1SHARES.Value;
Table1CURRENT_VAL.Value:=
FormatFloat('$###,##0.00;;(0.00#.##)',z);
end;
---------------------------------------------------------------
13. Select the DataSource Component on the form and Set the DataSet
Property to Table1
14. With DBGrid1
- Set the DataSource Property to DataSource1
- Set the DefaultDrawing Property to False
- Edit the OnDrawDataCell Event
OnDrawDataCell Event Code:
---------------------------------------------------------------
procedure TMyStockForm.DBGrid1DrawDataCell(Sender: TObject;
const Rect: TRect; Field: TField; State: TGridDrawState);
begin
{Optional code if you only want to color highlight the
CURRENT_VAL column}
{Use this as an example in combination to put color effects
on the grid}
{if Field.FieldName = 'CURRENT_VAL' then begin}
if (Table1PUR_PRICE.Value * Table1SHARES.Value) >=
AlertAmount then
DBGrid1.Canvas.Brush.Color:= ColorGrid1.ForeGroundColor
else
DBGrid1.Canvas.Brush.Color:= ColorGrid1.BackGroundColor;
DBGrid1.Canvas.FillRect(Rect);
{ end;}
DBGrid1.Canvas.TextOut(Rect.left + 2, Rect.top + 2,
Field.AsString);
end;
---------------------------------------------------------------
Commentary: This Event is called each time the cell is drawn.
In this Event, if the value of the stock
(Purchased Price * Shares) is greater than the
variable AlertValue, then the cells of the record
(row) is highlighted in the color specified in
ColorGrid.
Each individual cell is a Rect of TRect. It is
sent as a parameter of the Procedure. Normally,
if you weren't controlling the drawing of cells,
the grid would call both the FillRect and TextOut
methods of the canvas. It would also initializes
the Canvas' font and brush to the control font
and the cell color.
But since we are controlling the drawing of the
cell, we also have the ability to change the Canvas'
font and brush. This is what gives us the ability
to change the color of the cells.
15. Add three TLabel components, two TSpinEdit components, and one
TColorGrid component to the form.
16. Align the Label components and the SpinEdit components such
that Label1 is near SpinEdit1. The same is for Label2 and
SpinEdit2.
17. With Label1
- Set the Caption Property to
'Highlight current values greater than -->'
- Set the WordWrap Property to True
- Set the Alignment Property to taRightJustify
18. With Label2
- Set the Caption Property to
'Increment by:'
- Set the WordWrap Property to True
- Set the Alignment Property to taRightJustify
19. With SpinEdit1
- Set the Value Property to 100000
- Edit the OnChange Event
OnChange Event Code:
---------------------------------------------------------------
procedure TMyStockForm.SpinEdit1Change(Sender: TObject);
begin
AlertAmount:= SpinEdit1.Value;
dbGrid1.refresh;
end;
---------------------------------------------------------------
20. With SpinEdit2
- Set the Value Property to 10000
- Set the Increment Property to 1000
- Edit the OnChange Event
OnChange Event Code:
---------------------------------------------------------------
procedure TMyStockForm.SpinEdit2Change(Sender: TObject);
begin
spinedit1.increment:= spinedit2.value;
end;
---------------------------------------------------------------
21. With ColorGrid1
- Set the GridOrdering Property to 16x1
- Edit the OnChange Event
OnChange Event Code:
---------------------------------------------------------------
procedure TMyStockForm.ColorGrid1Change(Sender: TObject);
begin
dbGrid1.refresh;
end;
---------------------------------------------------------------
22. With Label3
- Set the WordWrap Property to True
- Set the Caption Property to
'To Change Foreground Color, left mouse click and drag FG.
To change Background Color, right mouse click and drag BG.'
23. With MyStockForm
- Edit the OnCreate Event
OnCreate Event Code:
---------------------------------------------------------------
procedure TMyStockForm.FormCreate(Sender: TObject);
begin
colorgrid1.foregroundindex:= 9;
colorgrid1.backgroundindex:= 15;
AlertAmount:= SpinEdit1.Value;
SpinEdit1.Increment:= SpinEdit2.Value;
end;
---------------------------------------------------------------
24. Compile and Run the Form.
Commentary: This demonstrated how you can control the cell
drawing on a grid. This knowledge can be applied
to other components where you also have the ability
to control the drawing.
Remember that within the OnDrawDataCell Event of the
TDBGrid, you have access to the Field information
and also the information of the record you're
currently on. With this, you have the flexibility
to create some very complex grids to display your
data.
*************************************************
{STOCKGRD.PAS}
unit Stockgrd;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, DB, DBTables, Grids, DBGrids, ExtCtrls,
Spin, ColorGrd;
type
TMyStockForm = class(TForm)
Table1: TTable;
DataSource1: TDataSource;
Table1SYMBOL: TStringField;
Table1SHARES: TFloatField;
Table1PUR_PRICE: TFloatField;
Table1PUR_DATE: TDateField;
Panel1: TPanel;
DBGrid1: TDBGrid;
Table1CURRENT_VAL: TStringField;
Label1: TLabel;
ColorGrid1: TColorGrid;
SpinEdit1: TSpinEdit;
Label2: TLabel;
SpinEdit2: TSpinEdit;
Label3: TLabel;
procedure DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
procedure Table1CalcFields(DataSet: TDataset);
procedure SpinEdit1Change(Sender: TObject);
procedure SpinEdit2Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ColorGrid1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
AlertAmount: Double;
end;
var
MyStockForm: TMyStockForm;
implementation
{$R *.DFM}
procedure TMyStockForm.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
{Optional code if you only want to color highlight the CURRENT_VAL column}
{Use this as an example in combination to put color effects on the grid}
{ if Field.FieldName = 'CURRENT_VAL' then begin}
if (Table1PUR_PRICE.Value * Table1SHARES.Value) >= AlertAmount then
DBGrid1.Canvas.Brush.Color:= ColorGrid1.ForeGroundColor
else
DBGrid1.Canvas.Brush.Color:= ColorGrid1.BackGroundColor;
DBGrid1.Canvas.FillRect(Rect);
{ end;}
DBGrid1.Canvas.textout(rect.left + 2, rect.top + 2, Field.AsString);
end;
procedure TMyStockForm.Table1CalcFields(DataSet: TDataset);
var
z: double;
begin
z:=Table1PUR_PRICE.Value * Table1SHARES.Value;
Table1CURRENT_VAL.Value:= FormatFloat('$###,##0.00;;(0.00#.##)',z);
end;
procedure TMyStockForm.SpinEdit1Change(Sender: TObject);
begin
AlertAmount:= SpinEdit1.Value;
dbGrid1.refresh;
end;
procedure TMyStockForm.SpinEdit2Change(Sender: TObject);
begin
spinedit1.increment:= spinedit2.value;
end;
procedure TMyStockForm.FormCreate(Sender: TObject);
begin
colorgrid1.foregroundindex:= 9;
colorgrid1.backgroundindex:= 15;
AlertAmount:= SpinEdit1.Value;
SpinEdit1.Increment:= SpinEdit2.Value;
end;
procedure TMyStockForm.ColorGrid1Change(Sender: TObject);
begin
dbGrid1.refresh;
end;
end.
-------------------------------------------------
{STOCKGRD.DFM}
object MyStockForm: TMyStockForm
Left = 143
Top = 83
BorderStyle = bsSingle
Caption = 'My Stock Portfolio'
ClientHeight = 417
ClientWidth = 544
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'System'
Font.Style = []
PixelsPerInch = 96
OnCreate = FormCreate
TextHeight = 16
object Panel1: TPanel
Left = 0
Top = 0
Width = 544
Height = 417
Align = alClient
BevelInner = bvLowered
BevelWidth = 2
BorderWidth = 1
TabOrder = 0
object Label1: TLabel
Left = 16
Top = 257
Width = 175
Height = 33
Alignment = taRightJustify
Caption = 'Highlight current values greater than -->'
WordWrap = True
end
object Label2: TLabel
Left = 351
Top = 258
Width = 68
Height = 32
Alignment = taRightJustify
Caption = 'Increment by:'
WordWrap = True
end
object Label3: TLabel
Left = 76
Top = 368
Width = 399
Height = 33
Caption = 'To Change Foreground Color, left mouse click and drag FG. To change Background Color, right mouse click and drag BG.'
WordWrap = True
end
object DBGrid1: TDBGrid
Left = 17
Top = 15
Width = 513
Height = 224
DataSource = DataSource1
DefaultDrawing = False
TabOrder = 0
TitleFont.Color = clWindowText
TitleFont.Height = -13
TitleFont.Name = 'System'
TitleFont.Style = []
OnDrawDataCell = DBGrid1DrawDataCell
end
object ColorGrid1: TColorGrid
Left = 24
Top = 306
Width = 496
Height = 54
GridOrdering = go16x1
TabOrder = 1
OnChange = ColorGrid1Change
end
object SpinEdit1: TSpinEdit
Left = 211
Top = 264
Width = 121
Height = 26
MaxValue = 0
MinValue = 0
TabOrder = 2
Value = 100000
OnChange = SpinEdit1Change
end
object SpinEdit2: TSpinEdit
Left = 433
Top = 264
Width = 91
Height = 26
Increment = 1000
MaxValue = 0
MinValue = 0
TabOrder = 3
Value = 1000
OnChange = SpinEdit2Change
end
end
object Table1: TTable
Active = True
OnCalcFields = Table1CalcFields
DatabaseName = 'DBDEMOS'
IndexFieldNames = 'SYMBOL'
TableName = 'HOLDINGS.DBF'
Left = 10
Top = 12
object Table1SYMBOL: TStringField
FieldName = 'SYMBOL'
Size = 7
end
object Table1SHARES: TFloatField
FieldName = 'SHARES'
end
object Table1PUR_PRICE: TFloatField
FieldName = 'PUR_PRICE'
end
object Table1PUR_DATE: TDateField
FieldName = 'PUR_DATE'
end
object Table1CURRENT_VAL: TStringField
Calculated = True
FieldName = 'CURRENT_VAL'
end
end
object DataSource1: TDataSource
DataSet = Table1
Left = 10
Top = 38
end
end
*************************************************