Mastodon
Programmierung

Adding a ComboBox to a cell

> I am using Delphi 2.0. I have a TStringGrid. In one of the columns, I want
> the cells to act as ComboBoxes; i.e. each of the cells in that column would
> have a small down arrow button which, when clicked, would show a
> drop-down list from which the user could choose an item for the cell.
>
> Any ideas on how I would go about this? Thanks.
>

there are several approaches here. A very simple one would just display a
genuine combobox on top of the cell when the user clicks on the cell. If you
want to see an arrow button in the cell in this scenario you would have to
draw it yourself in an OnDrawCell event.

Attach a combobox to a stringgrid column

[code lang=”delphi”]unit Unit1;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Grids;

type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
ComboBox1: TComboBox;
procedure ComboBox1Exit(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
private
{ Private declarations }
Procedure CMDialogKey( Var msg: TCMDialogKey );
message CM_DIALOGKEY;
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.CMDialogKey(var msg: TCMDialogKey);
begin
If Activecontrol = Combobox1 Then Begin
If msg.CharCode = VK_TAB Then Begin
// set focus back to the grid and pass the tab key to it
stringgrid1.setfocus;
stringgrid1.perform( WM_KEYDOWN, msg.charcode, msg.keydata );
// swallow this message
msg.result := 1;
Exit;
End;
End;
inherited;
end;

procedure TForm1.ComboBox1Exit(Sender: TObject);
begin
with sender as TCombobox do begin
hide;
if itemindex >= 0 then
with stringgrid1 do
cells[ col, row ] := items[itemindex];
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
combobox1.visible := false;
end;

procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol,
ARow: Integer; var CanSelect: Boolean);
var
R: TRect;
org: TPoint;
begin
With Sender As TStringgrid Do
If (ACol = 2) and (ARow >= FixedRows) Then Begin
// entered the column associated to the combobox
// get grid out of selection mode
perform( WM_CANCELMODE, 0, 0 );
// position the control on top of the cell
R := CellRect( Acol, Arow );
org:= Self.ScreenToClient( ClientToScreen( R.topleft ));
With combobox1 do begin
setbounds( org.X, org.Y, r.right-r.left, height );
itemindex := Items.IndexOf( Cells[ acol, arow ] );
Show;
BringTofront;
// focus the combobox and drop down the list
SetFocus;
DroppedDown := true;
end;
End;
end;

end.
[/code]
With a little modification the TStringgrid class can also be made to actually
parent a combonent. You need to modify the way it handles WM_COMMAND for this:

[code lang=”delphi”]unit ControlStringgrid;

interface

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

type
TControlStringgrid = class(TStringgrid)
private
{ Private declarations }
Procedure WMCommand( var msg: TWMCommand ); message WM_COMMAND;
protected
{ Protected declarations }
public
{ Public declarations }
published
{ Published declarations }
end;

procedure Register;

implementation

procedure Register;
begin
RegisterComponents(‘PBGoodies’, [TControlStringgrid]);
end;

{ TControlStringgrid }

procedure TControlStringgrid.WMCommand(var msg: TWMCommand);
begin
If EditorMode and ( msg.Ctl = InplaceEditor.Handle ) Then
inherited
Else
If msg.Ctl <> 0 Then
msg.result :=
SendMessage( msg.ctl, CN_COMMAND,
TMessage(msg).wparam,
TMessage(msg).lparam );
end;

end.
[/code]
Using this grid you can create a combobox as child of the grid, which has the
advantage that it will scroll with the grid while visible.

Peter Below (TeamB)

[tags]Delphi, Components, StringGrid[/tags]

0 Kommentare zu “Adding a ComboBox to a cell

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.