在Delphi XE的TStringGrid中使用TComboBox作为单元格编辑器

需要进行以下几步:
  1. 创建StringGrid,在OnSelectCell事件中显示ComboBox覆盖单元格作为编辑器
  2. 创建ComboBox,将其Parent设置为StringGrid,并将StringGrid的行高设置为ComboBox的高度
  3. 处理ComboBox的OnChange事件,修改StringGrid单元格的值
  4. 处理ComboBox的OnExit事件,隐藏ComboBox
  5. 创建新单元,定义同名类TStringGrid继承Vcl.Grids.TStringGrid并重写其WMCommand方法
  6. 在使用StringGrid的单元头部引用新单元,必须放在Vcl.Grids之后

以下是示例代码:

单元1:

点击(此处)折叠或打开

  1. unit Unit1;

  2. interface

  3. uses
  4.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
  5.   Vcl.Controls, Vcl.Forms, Vcl.StdCtrls, Vcl.Grids,
  6.   //必须将重定义的TStringGrid单元引用放置在Vcl.Grids之后
  7.   Unit2;

  8. type
  9.   TForm1 = class(TForm)
  10.     StringGrid1: TStringGrid;
  11.     procedure FormCreate(Sender: TObject);
  12.     procedure StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  13.       var CanSelect: Boolean);
  14.   private
  15.     FComboBox: TComboBox;
  16.     procedure OnComboBoxChange(Sender: TObject);
  17.     procedure OnComboBoxExit(Sender: TObject);
  18.     { Private declarations }
  19.   public
  20.     { Public declarations }
  21.   end;

  22. var
  23.   Form1: TForm1;

  24. implementation

  25. {$R *.dfm}

  26. procedure TForm1.FormCreate(Sender: TObject);
  27. begin
  28.   //创建ComboBox,也可以直接拖拽到Form
  29.   //此处只需要设置Parent := StringGrid1
  30.   FComboBox := TComboBox.Create(StringGrid1);
  31.   FComboBox.Parent := StringGrid1;
  32.   FComboBox.Items.Add('Item1');
  33.   FComboBox.Items.Add('Item2');
  34.   FComboBox.OnChange := OnComboBoxChange;
  35.   FComboBox.OnExit := OnComboBoxExit;
  36.   FComboBox.Visible := False;
  37.   //ComboBox高度是固定不能改变的
  38.   //因此设置StringGrid1的行高与ComboBox高度一致
  39.   StringGrid1.DefaultRowHeight := FComboBox.Height;
  40. end;

  41. procedure TForm1.OnComboBoxChange(Sender: TObject);
  42. begin
  43.   StringGrid1.Cells[StringGrid1.Col, StringGrid1.Row] := FComboBox.Text;
  44. end;

  45. procedure TForm1.OnComboBoxExit(Sender: TObject);
  46. begin
  47.   FComboBox.Visible := False;
  48. end;

  49. procedure TForm1.StringGrid1SelectCell(Sender: TObject; ACol, ARow: Integer;
  50.   var CanSelect: Boolean);
  51. var
  52.   ARect: TRect;
  53. begin
  54.   //示例代码仅在第二列中使用ComboBox作为编辑器
  55.   if CanSelect and (ACol = 1) then
  56.   begin
  57.     FComboBox.ItemIndex := FComboBox.Items.IndexOf
  58.       (StringGrid1.Cells[ACol, ARow]);
  59.     //使ComboBox显示并覆盖住选中单元格
  60.     ARect := StringGrid1.CellRect(ACol, ARow);
  61.     FComboBox.Left := ARect.Left;
  62.     FComboBox.Top := ARect.Top;
  63.     FComboBox.Width := ARect.Right - ARect.Left;
  64.     FComboBox.Visible := True;
  65.     FComboBox.SetFocus;
  66.   end;
  67. end;

  68. end.

单元2:

点击(此处)折叠或打开

  1. unit Unit2;

  2. interface

  3. uses
  4.   Vcl.Grids, Winapi.Windows, Winapi.Messages, Vcl.Controls;

  5. type
  6.   TStringGrid = class(Vcl.Grids.TStringGrid)
  7.   private
  8.     procedure WMCommand(var AMessage: TWMCommand); message WM_COMMAND;
  9.   end;

  10. implementation

  11. { TStringGrid }

  12. procedure TStringGrid.WMCommand(var AMessage: TWMCommand);
  13. begin
  14.   //如果当前是StringGrid内置编辑框,调用父类方法
  15.   //否则向控件发送CN_COMMAND事件
  16.   if (InplaceEditor <> nil) and (AMessage.Ctl = InplaceEditor.Handle) then
  17.     inherited
  18.   else if AMessage.Ctl <> 0 then
  19.   begin
  20.     AMessage.Result := SendMessage(AMessage.Ctl, CN_COMMAND,
  21.       TMessage(AMessage).WParam, TMessage(AMessage).LParam);
  22.   end;
  23. end;

  24. end.

说明:
  1. TStringGrid只支持内置的输入框做为单元格编辑器,所以只好放置一个ComboBox并覆盖住要编辑的单元格
  2. TStringGrid祖先类TCustomGrid在WMCommand方法中限制了只处理InplaceEditor,所以需要重写这个方法
也可以继承TStringGrid而不是使用同名类,再全部动态创建,但是太麻烦而且基本没什么区别

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/634491/viewspace-2155218/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/634491/viewspace-2155218/

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值