2004. június 29., kedd
Combobox instead inplace editor in TStringGrid
Problem/Question/Abstract:
How can I use a combobox as inplace editor in standard TStringGrid?
Answer:
I wrote a small app which demonstrates how you can use the some combobox instead standard inplace editor in TStringGrid component.
Also in this app you can view how change font and/or alignment for some cells.
The form contents as text:
object frmMain: TfrmMain
Left = 200
Top = 108
Width = 510
Height = 382
Caption = 'Example: TStringGrid advanced using'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object StringGrid1: TStringGrid
Left = 24
Top = 152
Width = 457
Height = 161
ColCount = 2
DefaultColWidth = 200
DefaultRowHeight = 21
RowCount = 9
TabOrder = 0
OnDrawCell = StringGrid1DrawCell
OnSelectCell = StringGrid1SelectCell
ColWidths = (
118
296)
end
object cbInplaceComboBox: TComboBox
Left = 32
Top = 320
Width = 145
Height = 21
Style = csDropDownList
ItemHeight = 13
Items.Strings = (
'1 value'
'2 value'
'3 value'
'4 value'
'5 value'
'6 value'
'7 value'
'8 value'
'9 value')
TabOrder = 1
OnChange = cbInplaceComboBoxChange
end
object btnClose: TButton
Left = 416
Top = 320
Width = 75
Height = 25
Cancel = True
Caption = '&Close'
default = True
TabOrder = 2
OnClick = btnCloseClick
end
object MemoDescription: TMemo
Left = 24
Top = 8
Width = 457
Height = 129
Font.Charset = DEFAULT_CHARSET
Font.Color = clNavy
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
Lines.Strings = (
'In this sample I shows how you can:'
' '
'1. change the inplace editor for second column'
' from standard inplace editor to user TComboBox component'
' '
' view the next procedures:'
' - TfrmMain.FormCreate'
' - TfrmMain.CMDialogKey'
' - TfrmMain.cbInplaceComboBoxChange'
' - TfrmMain.StringGrid1SelectCell'
' '
'2. draw the cell values with different fonts'
' '
' view the next procedure:'
' - TfrmMain.StringGrid1DrawCell'
' '
'3. change alignment for cells'
' '
' view the next procedure:'
' - TfrmMain.StringGrid1DrawCell')
ParentFont = False
ScrollBars = ssVertical
TabOrder = 3
end
end
The pas - file for same form:
unit Main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids;
type
TfrmMain = class(TForm)
StringGrid1: TStringGrid;
cbInplaceComboBox: TComboBox;
btnClose: TButton;
MemoDescription: TMemo;
procedure FormCreate(Sender: TObject);
procedure cbInplaceComboBoxChange(Sender: TObject);
procedure StringGrid1SelectCell(Sender: TObject; Col, Row: Integer;
var CanSelect: Boolean);
procedure StringGrid1DrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
procedure btnCloseClick(Sender: TObject);
private
{ Private declarations }
procedure CMDialogKey(var msg: TCMDialogKey); message CM_DIALOGKEY;
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.DFM}
procedure TfrmMain.FormCreate(Sender: TObject);
var
i: Integer;
begin
StringGrid1.DefaultRowHeight := cbInplaceComboBox.Height;
cbInplaceComboBox.Visible := False;
StringGrid1.Cells[0, 0] := 'Row No';
StringGrid1.Cells[1, 0] := 'Values (from Combobox)';
for i := 1 to StringGrid1.RowCount - 1 do
StringGrid1.Cells[0, i] := IntToStr(i);
end;
procedure TfrmMain.CMDialogKey(var msg: TCMDialogKey);
begin
if (ActiveControl = cbInplaceComboBox) then
begin
if (msg.CharCode = VK_TAB) then
begin
//set focus back to the grid and pass the tab key to it
cbInplaceComboBox.SetFocus;
cbInplaceComboBox.Perform(WM_KEYDOWN, msg.CharCode, msg.KeyData);
// swallow this message
msg.result := 1;
Exit;
end;
end;
inherited;
end;
procedure TfrmMain.cbInplaceComboBoxChange(Sender: TObject);
var
intRow: Integer;
begin
inherited;
{Get the ComboBox selection and place in the grid}
with cbInplaceComboBox do
begin
intRow := StringGrid1.Row;
if (StringGrid1.Col = 2) then
StringGrid1.Cells[2, intRow] := Items[ItemIndex]
else
StringGrid1.Cells[StringGrid1.Col, intRow] := Items[ItemIndex];
Visible := False;
end;
StringGrid1.SetFocus;
end;
procedure TfrmMain.StringGrid1SelectCell(Sender: TObject; Col, Row: Integer;
var CanSelect: Boolean);
var
R: TRect;
begin
if ((Col = 1) and (Row <> 0)) then
begin
{Size and position the combo box to fit the cell}
R := StringGrid1.CellRect(Col, Row);
R.Left := R.Left + StringGrid1.Left;
R.Right := R.Right + StringGrid1.Left;
R.Top := R.Top + StringGrid1.Top;
R.Bottom := R.Bottom + StringGrid1.Top;
{Show the combobox}
with cbInplaceComboBox do
begin
Left := R.Left + 1;
Top := R.Top + 1;
Width := (R.Right + 1) - R.Left;
Height := (R.Bottom + 1) - R.Top;
ItemIndex := Items.IndexOf(StringGrid1.Cells[Col, Row]);
Visible := True;
SetFocus;
end;
end;
CanSelect := True;
end;
procedure TfrmMain.StringGrid1DrawCell(Sender: TObject; Col, Row: Integer;
Rect: TRect; State: TGridDrawState);
const
AlignFlags: array[TAlignment] of Integer =
(DT_LEFT or DT_VCENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
DT_RIGHT or DT_VCENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX,
DT_CENTER or DT_VCENTER or DT_WORDBREAK or DT_EXPANDTABS or DT_NOPREFIX);
var
s: string;
begin
inherited;
with Rect do
begin
Left := Left + 2;
Top := Top + 2;
Right := Right - 5
end;
s := StringGrid1.Cells[Col, Row];
if (Row = 0) and (Col < StringGrid1.ColCount) then
begin
StringGrid1.Canvas.Font.Style := StringGrid1.Canvas.Font.Style + [fsBold];
StringGrid1.Canvas.Brush.Color := StringGrid1.FixedColor;
StringGrid1.Canvas.FillRect(Rect);
DrawText(StringGrid1.Canvas.Handle,
PChar(s), Length(s),
Rect, AlignFlags[taCenter]);
end
else if (Col = 0) and (Row > 0) and (Row < StringGrid1.RowCount) then
begin
StringGrid1.Canvas.FillRect(Rect);
DrawText(StringGrid1.Canvas.Handle,
PChar(s), Length(s),
Rect, AlignFlags[taRightJustify]);
end;
end;
procedure TfrmMain.btnCloseClick(Sender: TObject);
begin
Close
end;
end.
Component Download: http://www.geocities.com/mshkolnik/FAQ/strgrid.zip
Feliratkozás:
Megjegyzések küldése (Atom)
Nincsenek megjegyzések:
Megjegyzés küldése