需要进行以下几步:
- 创建StringGrid,在OnSelectCell事件中显示ComboBox覆盖单元格作为编辑器
- 创建ComboBox,将其Parent设置为StringGrid,并将StringGrid的行高设置为ComboBox的高度
- 处理ComboBox的OnChange事件,修改StringGrid单元格的值
- 处理ComboBox的OnExit事件,隐藏ComboBox
- 创建新单元,定义同名类TStringGrid继承Vcl.Grids.TStringGrid并重写其WMCommand方法
- 在使用StringGrid的单元头部引用新单元,必须放在Vcl.Grids之后
以下是示例代码:
单元1:
点击(此处)折叠或打开
- unit Unit1;
-
- interface
-
- uses
- Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
- Vcl.Controls, Vcl.Forms, Vcl.StdCtrls, Vcl.Grids,
- //必须将重定义的TStringGrid单元引用放置在Vcl.Grids之后
- Unit2;
-
- type
- TForm1 = class(TForm)
- StringGrid1: TStringGrid;
- procedure FormCreate(Sender: TObject);
- procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
- var CanSelect: Boolean);
- private
- FComboBox: TComboBox;
- procedure OnComboBoxChange(Sender: TObject);
- procedure OnComboBoxExit(Sender: TObject);
- { Private declarations }
- public
- { Public declarations }
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.dfm}
-
- procedure TForm1.FormCreate(Sender: TObject);
- begin
- //创建ComboBox,也可以直接拖拽到Form
- //此处只需要设置Parent := StringGrid1
- FComboBox := TComboBox.Create(StringGrid1);
- FComboBox.Parent := StringGrid1;
- FComboBox.Items.Add('Item1');
- FComboBox.Items.Add('Item2');
- FComboBox.OnChange := OnComboBoxChange;
- FComboBox.OnExit := OnComboBoxExit;
- FComboBox.Visible := False;
- //ComboBox高度是固定不能改变的
- //因此设置StringGrid1的行高与ComboBox高度一致
- StringGrid1.DefaultRowHeight := FComboBox.Height;
- end;
-
- procedure TForm1.OnComboBoxChange(Sender: TObject);
- begin
- StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row] := FComboBox.Text;
- end;
-
- procedure TForm1.OnComboBoxExit(Sender: TObject);
- begin
- FComboBox.Visible := False;
- end;
-
- procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
- var CanSelect: Boolean);
- var
- ARect: TRect;
- begin
- //示例代码仅在第二列中使用ComboBox作为编辑器
- if CanSelect and (ACol = 1) then
- begin
- FComboBox.ItemIndex := FComboBox.Items.IndexOf
- (StringGrid1.Cells[ACol, ARow]);
- //使ComboBox显示并覆盖住选中单元格
- ARect := StringGrid1.CellRect(ACol, ARow);
- FComboBox.Left := ARect.Left;
- FComboBox.Top := ARect.Top;
- FComboBox.Width := ARect.Right - ARect.Left;
- FComboBox.Visible := True;
- FComboBox.SetFocus;
- end;
- end;
-
- end.
单元2:
点击(此处)折叠或打开
- unit Unit2;
-
- interface
-
- uses
- Vcl.Grids, Winapi.Windows, Winapi.Messages, Vcl.Controls;
-
- type
- TStringGrid = class(Vcl.Grids.TStringGrid)
- private
- procedure WMCommand(var AMessage: TWMCommand); message WM_COMMAND;
- end;
-
- implementation
-
- { TStringGrid }
-
- procedure TStringGrid.WMCommand(var AMessage: TWMCommand);
- begin
- //如果当前是StringGrid内置编辑框,调用父类方法
- //否则向控件发送CN_COMMAND事件
- if (InplaceEditor <> nil) and (AMessage.Ctl = InplaceEditor.Handle) then
- inherited
- else if AMessage.Ctl <> 0 then
- begin
- AMessage.Result := SendMessage(AMessage.Ctl, CN_COMMAND,
- TMessage(AMessage).WParam, TMessage(AMessage).LParam);
- end;
- end;
-
- end.
说明:
- TStringGrid只支持内置的输入框做为单元格编辑器,所以只好放置一个ComboBox并覆盖住要编辑的单元格
- TStringGrid祖先类TCustomGrid在WMCommand方法中限制了只处理InplaceEditor,所以需要重写这个方法
也可以继承TStringGrid而不是使用同名类,再全部动态创建,但是太麻烦而且基本没什么区别
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/634491/viewspace-2155218/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/634491/viewspace-2155218/