找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 4947|回复: 20

[求助] 如何让Grid捕获键盘事件?

[复制链接]

已领礼包: 1个

财富等级: 恭喜发财

发表于 2013-5-6 01:27:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 yxpxa 于 2013-5-9 00:21 编辑

一、Grid控件有 OnKeyDown 事件,但是在单元格输入的时候该事件是不响应的。
目的是想实现想 EXCEL 一样的输入方式,回车或按方向键就能到下一个单元格。
应该如何解决?
二、单元格的 OnSelChanged 事件好像慢了一拍,单元格输入完毕该事件也不响应。
必须点一下别的地方,该事件才发生。
如何解决?
help me. thanks

请点击此处下载

查看状态:需购买或无权限

您的用户组是:游客

文件名称:test.rar 
下载次数:12  文件大小:5.54 KB 
下载权限: 不限 以上  [免费赚D豆]

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 344个

财富等级: 日进斗金

发表于 2013-5-6 10:52:22 | 显示全部楼层
一、在KeyDown事件中添加如下代码可以实现你的要求:\
[pcode=lisp,true](defun c:Grid_Dcl-1_grid1_OnKeyDown (Character RepeatCount Flags / l row col TotalCol TotalRow)
  (setq l (dcl_Grid_GetCurCell Grid_Dcl-1_grid1)
        row (car l)
        col (cadr l)
        TotalCol (dcl_Grid_GetColumnCount Grid_Dcl-1_grid1)
        TotalRow (dcl_Grid_GetRowCount Grid_Dcl-1_grid1)
        )
  (cond ((= "\t" Character) ;_ Tab键,光标右移一列
      (setq col (1+ col))
      (if (= col TotalCol) (setq col 1 row (1+ row))) ;_ 若到头了,回到起始列
     (dcl_Grid_SetCurCell Grid_Dcl-1_grid1 row col)
     )
    ((= "\r" Character) ;_ 回车键,光标下移一行
     (setq row (1+ row)) ;_ 光标下移一行
     (if (= row TotalRow) (setq row 1 col (1+ col))) ;_ 若到头了,回到起始行
     (if (= col TotalCol) (setq col 1)) ;_ 若到头了,回到起始列
     (dcl_Grid_SetCurCell Grid_Dcl-1_grid1 row col)
     )
    )
)[/pcode]
二、OnSelChanged事件本来就是选择的单元格变化了才反映!你应该用OnEndLabelEdit事件来响应单元格的数据编辑变化!

评分

参与人数 1D豆 +6 收起 理由
XDSoft + 6 技术引导讨论和指点奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-6 11:02:13 | 显示全部楼层
开始编辑时你可以绘制一个TextBox在Grid之上,用TextBox代替Grid单元格。

点评

Grid是可以编辑的,为什么要加textbox?  发表于 2013-5-6 11:17
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-6 17:37:53 | 显示全部楼层

我相信你是误解LZ的意思了,GRID在编辑时是无法响应KeyDown事件的,ComboBox的选择改变事件也是无法响应的,所以按方向键是无法达到切换单元格的,而利用TexBox的KeyDown就没问题了。

点评

确实我理解错了!在编辑状态是无法响应键盘的!  发表于 2013-5-6 21:13
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-6 17:50:12 | 显示全部楼层
Gdlprfcu 发表于 2013-5-6 17:37
我相信你是误解LZ的意思了,GRID在编辑时是无法响应KeyDown事件的,ComboBox的选择改变事件也是无法响应的 ...

问个问题,Textbox和ComboBox 怎么放到一个格子里面?
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-6 18:09:33 | 显示全部楼层
菜菜学ODCL 发表于 2013-5-6 17:50
问个问题,Textbox和ComboBox 怎么放到一个格子里面?

首先你在创建对话框的时候就创建这个TextBox或ComboBox并且顶置或后面调用的时候用dcl_Control_ZOrder函数顶置,把TAB停留、可用、可见取消或显示时指定,在Grid开始编辑事件使用dcl_Control_GetPos 函数获得Grid的位置,再用dcl_Grid_GetColumnWidth函数获得列宽计算出单元格位置和大小,跟着设置你的TextBox或ComboBox位置和大小和设置焦点就可以啦。

评分

参与人数 1贡献 +2 收起 理由
XDSoft + 2 技术引导讨论和指点奖!

查看全部评分

论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-5-6 18:51:15 | 显示全部楼层
我做了一个演示,看看楼主是需要这样的吗? 按光标键下箭头在GRID格子间移动。


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

 楼主| 发表于 2013-5-6 19:38:13 | 显示全部楼层
本帖最后由 yxpxa 于 2013-5-6 19:40 编辑

楼上高人!
让 TextBox 跟着 grid 单元格移动,这个创意我咋没想到,试一试,弄好把代码传上来。
grid 单元格的行高好像是固定的,列宽才能调整
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-5-6 19:38:34 | 显示全部楼层
如果上面的演示是楼主需要的,那么这个官方带的例子就是用的OnSelChanged

[pcode=lisp,true]
(defun c:Grid_Dcl-1_grid1_OnSelChanged (nRow nCol / newValue)
        (setq newValue (strcat "Ereignis: OnSelChanged
Argumente: nRow: "         (itoa nRow)
                                                   " ; nCol: "
                                                   (itoa nCol)
                                   )
        )
        (dcl_ListBox_SetTopIndex Grid_Dcl-1_LB-Status (dcl_ListBox_AddString Grid_Dcl-1_LB-Status newValue))
)
[/pcode]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

 楼主| 发表于 2013-5-6 19:46:34 | 显示全部楼层
感谢XDsoft,如果你把单元格的 style 设置 6  字符输入状态,按方向键是无效的。

[pcode=lisp,true]
(defun c:Test_Form1_Grid_OnKeyDown (Character RepeatCount Flags /)
  (princ "\ncharacter:")
  (princ character)
  (princ "\nRepeatcount:")
  (princ Repeatcount)
  (princ "\nFlags:")
  (princ Flags)
  (princ)
)
[/pcode]
没有任何反应,示例如下:

请点击此处下载

查看状态:需购买或无权限

您的用户组是:游客

文件名称:test.rar 
下载次数:7  文件大小:1.1 KB 
下载权限: 不限 以上  [免费赚D豆]



777.jpg
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-6 21:19:26 | 显示全部楼层
又学到一招了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 145个

财富等级: 日进斗金

发表于 2013-5-6 22:20:41 | 显示全部楼层
yxpxa 发表于 2013-5-6 19:46
感谢XDsoft,如果你把单元格的 style 设置 6  字符输入状态,按方向键是无效的。

字符应该不行,要支持你移动走了,那你怎么编辑里面的字符啊。

字符的CELL你也想用光标移动走?

你用G版主的判断下按下下箭头键,然后看看成不成。

在用上面GDLPRFCU朋友的方法也做下,希望有收获贴上来。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

 楼主| 发表于 2013-5-7 07:01:30 | 显示全部楼层
XDSoft 发表于 2013-5-6 22:20
字符应该不行,要支持你移动走了,那你怎么编辑里面的字符啊。

字符的CELL你也想用光标移动走?


感谢!已经解决
Excel 在输入的时候就可以按下方向键
http://bbs.xdcad.net/forum.php?m ... 1&extra=#pid3448588
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2013-5-8 21:00:43 | 显示全部楼层
本帖最后由 Gdlprfcu 于 2013-5-8 21:04 编辑

为了证明自己的想法,也做了一个TEXTBOX替换GRID输入方法,却发现了个至命问题:当行或列超出Grid控件的时候,我没法计算到单元格的准确位置,所以这种方法只能在控件能完全显示行和列的情况下使用,但这样就完全失去Grid控件真正作用了,LZ你另一帖所说的BUG你可以试下我的方法。
未命名2.jpg

未命名3.jpg

[pcode=lisp,true](if(setq dclpath(findfile "GridForm.lsp"))
        (progn
                (dcl_Project_Import (load dclpath))
                )
        (progn
                (princ "找不到DCL文件,程序退出。")
                (vl-exit-with-error "错误,找不到DCL文件")
                )
        )

(defun c:ShowForm(/ GetCellPos  c:Form_OnCancelClose)
        ;;-----------获取单元格相对对话框的位置和尺寸函数---------------
        (defun GetCellPos(Row Column /)
                (setq gridpos(dcl_Control_GetPos  Grid))
                (setq Wide(dcl_Grid_GetColumnWidth  Grid Column))
                (setq High(dcl_Control_GetRowHeight  Grid))
                (setq x(car gridpos))
                (setq n 0)
                (repeat Column
                        (setq x(+ x (dcl_Grid_GetColumnWidth  Grid n)))
                        (setq n(1+ n))
                        )
                (setq x(+ x 3));有误差
                (setq y(+(* Row High)High 10));有误差
                (list x y Wide High)
                )
        ;;----------------对话框初始化事件-------------
        (defun c:Form_OnInitialize (/ n)
                (setq n 0)
                (repeat 20
                        (dcl_Grid_AddString Grid CellLabels "" )
                        (dcl_Grid_SetCellText Grid n 0 (itoa(1+ n)))
                        (setq n(1+ n))
                        )
               
                )
        ;;----------------对话框取消关闭事件,作用:防止回车、Esc键关闭对话框-------------
        (defun c:Form_OnCancelClose (Reason /)
                (cond
                        ((= Reason 1)
                                (setq *Cancel* t)
                                (dcl_Control_SetFocus Grid)
                                )
                        ((and *EditColumn* *EditRow*(= Reason 0))
                                (dcl_Grid_SetCurCell Grid (1+ *EditRow*)   *EditColumn*)
                                (dcl_Control_SetFocus Grid)
                                )
                        ; ((and(>(car(setq lis(dcl_Grid_GetCurCell Grid)))0)(>(cadr lis)0))
                                ; (dcl_Grid_SetCurCell Grid (1+ (car lis))   (cadr lis))
                                ; )
                        )
                t
                )

        ;;-----------表格双击事件,作用:激活TextBox并设置焦点---------------
        (defun c:Grid_On双击 (Row  Column   /)
                (setq *EditRow* Row *EditColumn* Column)
                (setq text(dcl_Grid_GetCellText Grid Row  Column  ))
                (dcl_Control_SetText TextBoxName text )
                (dcl_Control_SetVisible TextBoxName t)
                (dcl_Control_SetEnabled TextBoxName t)
                (dcl_TextBox_SetSel TextBoxName (setq n(strlen text)) (1+ n))
                )
        ;;----------表格选择改变事件,作用:移动需要的控件到选择的单元----------------
        (defun c:Grid_OnSelChanged (Row  Column  /)
                (setq Cellpos(GetCellPos Row Column))
                (dcl_Control_SetPos TextBoxName (car Cellpos)(cadr Cellpos)(caddr Cellpos)(cadddr Cellpos))
                )
        ;;----------表格键盘按下事件,作用:按需激活TextBox并设置焦点、----------------
        (defun c:Grid_OnKeyDown (Character  RepeatCount  Flags  / lis)
                ; (dcl_MessageBox (strcat "按下的键码为" (itoa flags)) "提示")
                (setq lis(dcl_Grid_GetCurCell Grid))
                (if (and(>=(car lis)0)(>=(cadr lis)0))
                        (progn
                                (cond
                                        ((= Flags 28)
                                                (dcl_Grid_SetCurCell Grid (1+ (car lis))   (cadr lis))
                                                )
                                        ((and (/= Flags 331) (/= Flags 333)(/= Flags 328)(/= Flags 336));具体要排除的还有很多。。。。
                                        ; (or(and (> Flags 1)(< Flags 13))(and (> Flags 15)(< Flags 28)))
                                                (setq *EditRow*(car lis)*EditColumn*(cadr lis))
                                                (dcl_Control_SetText TextBoxName Character )
                                                (dcl_Control_SetVisible TextBoxName t)
                                                (dcl_Control_SetEnabled TextBoxName t)
                                                (dcl_TextBox_SetSel TextBoxName 1 2)
                                                )
                                        )
                                )
                        )
                )
        ;;----------TextBox失去焦点事件,作用:隐藏自身并把值返回给表格----------------
        (defun c:TextBoxName_OnKillFocus (/)
                (if (and *EditRow* *EditColumn*(not *Cancel*));不是按Esc键取消,就把值返回给Grid
                        (dcl_Grid_SetCellText Grid *EditRow* *EditColumn* (dcl_Control_GetText TextBoxName))
                        )
                (setq *EditRow* nil *EditColumn* nil *Cancel* nil)
                (dcl_Control_SetText TextBoxName "")
                (dcl_Control_SetVisible TextBoxName nil)
                (dcl_Control_SetEnabled TextBoxName nil)
                (dcl_Control_SetFocus Grid)
        )
        ;;----------TextBox键盘按下事件--------------------------------
        (defun c:TextBoxName_OnKeyDown (Character  RepeatCount  Flags  /)
                  ; (dcl_MessageBox (strcat "按下的键码为" (itoa flags)) "提示")
                (cond
                        ((= Flags 331);向左
                                (dcl_Grid_SetCurCell Grid *EditRow*   (1- *EditColumn*))
                                (dcl_Control_SetFocus Grid)
                                )
                        ((= Flags 333);向右
                                (dcl_Grid_SetCurCell Grid *EditRow*   (1+ *EditColumn*))
                                (dcl_Control_SetFocus Grid)
                                )
                        ((= Flags 328);向上
                                (dcl_Grid_SetCurCell Grid (1- *EditRow*)   *EditColumn*)
                                (dcl_Control_SetFocus Grid)
                                )
                        ((= Flags 336);向下
                                (dcl_Grid_SetCurCell Grid (1+ *EditRow*)   *EditColumn*)
                                (dcl_Control_SetFocus Grid)
                                );;缺点TAB键不能换列
                        )
                        
                )
        ;----------关闭按钮点击事件-----------------------
        (defun c:GridForm_Form1_TextButton1_On点击 (/)
                (dcl_Form_Close Form )
                )
        (dcl_form_show Form)
        )
        [/pcode]

Grid.lsp

4.31 KB, 下载次数: 11, 下载积分: D豆 -1 , 活跃度 1

GridForm.lsp

1.61 KB, 下载次数: 8, 下载积分: D豆 -1 , 活跃度 1

点评

我找到了bug的解决办法,可惜你们已经不在了  详情 回复 发表于 2019-9-21 00:26
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 19个

财富等级: 恭喜发财

发表于 2013-5-8 21:08:01 | 显示全部楼层
本帖最后由 Lisphk 于 2013-5-8 21:09 编辑
yxpxa 发表于 2013-5-7 07:01
感谢!已经解决
Excel 在输入的时候就可以按下方向键
http://bbs.xdcad.net/forum.php?m ... 1&extra ...

EXCEL在单击单元格的时候可以移动走,双击编辑后就不行了。主要是别让单元格保持焦点处于激活输入光标闪动状态,我认为。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-5-29 11:15 , Processed in 0.237727 second(s), 70 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表