注册 登录
编程论坛 VFP论坛

表单中grid 控件使用的问题,求指教

huowang 发布于 2022-09-07 13:53, 2776 次点击
我的 grid 控件 数据源直接就是一张本地表,我想在grid 控件上单击的时候不切入单元格,只在双击某个单元格的时候可以切入这个单元格进行修改
目前我 把 grid 控件的 allowcellselecion ,设置了.F. ,beforrowcolchange 也设置了allowcellselecion ,设置了.F.,这两个设置好了以后,基本达到我想要的效果,本来我想在dblcick事件中写 allowcellselecion=.T. 就能实现双击进入单元格 ,但我双击后却没有切入单元格,该怎么做呢
只有本站会员才能查看附件,请 登录

25 回复
#2
laowan0012022-09-07 14:46
allowcellselecion=.T. 时,单元格就没有双击事件了
#3
huowang2022-09-07 17:26
那我想实现这个功能该怎么做呢
#4
吹水佬2022-09-07 17:35
简单试了一下,有个问题:第一次双击输入不了,再点击其他行或列后双击就可以输入了?
程序代码:
CREATE CURSOR tt (F1 C(10), F2 C(10), F3 I)
INSERT INTO tt VALUES ("ABC", "123456", 101)
INSERT INTO tt VALUES ("DEF", "654321", 202)
INSERT INTO tt VALUES ("GHI", "456123", 303)
GO TOP
of = CREATEOBJECT("form1")
of.show(1)
RETURN

DEFINE CLASS form1 as Form
    ADD OBJECT grid1 as myGrid
ENDDEFINE

DEFINE CLASS myGrid as Grid
    AllowCellSelection = .f.
    PROCEDURE DblClick
        this.AllowCellSelection = .t.
        this.ReadOnly = .f.
    ENDPROC
    PROCEDURE AfterRowColChange(nColIndex)
        IF this.RowColChange != 0
            this.AllowCellSelection = .f.
        ENDIF  
    ENDPROC
ENDDEFINE
#5
huowang2022-09-07 19:30
对,其实我也发现了这个问题,如果我afterrowcolchange 事件中 写 allowcellselecion=.T. ,也是这样 第一次双击输入不了,再点击其他行或列后双击就可以输入,但这不是我想要的效果
#6
huowang2022-09-07 21:13
afterrowcolchange 事件中 写 allowcellselecion=.T. 发现也基本可以了,但就是第一次双击无效,不知道怎么解决
#7
csyx2022-09-07 21:22
开打调试器的事件跟踪可以看到,Before/AfterRowColChange事件是在click事件之前触发的,所以第一次会无效
#8
csyx2022-09-07 21:25
表格的双击事件代码这样试试
PROCEDURE DblClick
    Local oo as TextBox
    Local array aTemp[1]
    this.AllowCellSelection = .T.
    AMouseObj(aTemp)
    oo = aTemp[1]
    oo.SetFocus()
EndProc
上面只是简单的试验一下,没做任何错误判断处理
#9
sam_jiang2022-09-07 21:27
以下是引用csyx在2022-9-7 21:22:38的发言:

开打调试器的事件跟踪可以看到,Before/AfterRowColChange事件是在click事件之前触发的,所以第一次会无效



#10
sam_jiang2022-09-07 21:32
cell的单击事件设置为nodefault,或者readonly,或者enable=.f.,双击事件后恢复为.t.,lostfocus再设为.f.,应该就可以了。
#11
吹水佬2022-09-08 07:41
如果不是要求特定视觉效果,可以试试封装一个textbox作为grid的编辑控件,用grid的readonly来控制编辑
#12
laowan0012022-09-08 07:57
以下是引用huowang在2022-9-7 17:26:01的发言:

那我想实现这个功能该怎么做呢


介绍一下我的做法:
grid的allowcellselecion=.F.,双击时改成.T.,afterrowcolchange 时把allowcellselecion改成.F.
这样做步骤上并没有减少,但有一个好处,就是可以防止操作者不小心输入了单元格内容

[此贴子已经被作者于2022-9-8 09:44编辑过]

#13
wj02162022-09-08 09:08


[此贴子已经被作者于2022-9-8 09:09编辑过]

#14
吹水佬2022-09-08 10:35
回复 11楼 吹水佬
程序代码:
CREATE CURSOR tt (F1 C(10), F2 C(10), F3 I)
INSERT INTO tt VALUES ("ABC", "123456", 101)
INSERT INTO tt VALUES ("DEF", "654321", 202)
INSERT INTO tt VALUES ("GHI", "456123", 303)
GO TOP
of = CREATEOBJECT("form1")
of.show(1)
RETURN

DEFINE CLASS form1 as Form
    ADD OBJECT grid1 as myGrid
ENDDEFINE

DEFINE CLASS myGrid as Grid
    ReadOnly = .t.
    PROCEDURE Init
        FOR EACH oCol IN this.Columns
            IF oCol.CurrentControl=="Text1"
                oCol.RemoveObject("Text1")
                oCol.AddObject("Text1","myTextbox",this)
            ENDIF
        ENDFOR
    ENDPROC
ENDDEFINE

DEFINE CLASS myTextbox as TextBox
    Visible = .t.
    grid = NULL
    PROCEDURE Init(grid)
        this.grid = grid
    ENDPROC
    PROCEDURE DblClick
        this.grid.ReadOnly = .f.
    ENDPROC
    PROCEDURE LostFocus
        this.grid.ReadOnly = .t.
    ENDPROC
ENDDEFINE
#15
sam_jiang2022-09-08 10:57
以下是引用吹水佬在2022-9-8 10:35:32的发言:

CREATE CURSOR tt (F1 C(10), F2 C(10), F3 I)
INSERT INTO tt VALUES ("ABC", "123456", 101)
INSERT INTO tt VALUES ("DEF", "654321", 202)
INSERT INTO tt VALUES ("GHI", "456123", 303)
GO TOP
of = CREATEOBJECT("form1")
of.show(1)
RETURN

DEFINE CLASS form1 as Form
    ADD OBJECT grid1 as myGrid
ENDDEFINE

DEFINE CLASS myGrid as Grid
    ReadOnly = .t.
    PROCEDURE Init
        FOR EACH oCol IN this.Columns
            IF oCol.CurrentControl=="Text1"
                oCol.RemoveObject("Text1")
                oCol.AddObject("Text1","myTextbox",this)
            ENDIF
        ENDFOR
    ENDPROC
ENDDEFINE

DEFINE CLASS myTextbox as TextBox
    Visible = .t.
    grid = NULL
    PROCEDURE Init(grid)
        this.grid = grid
    ENDPROC
    PROCEDURE DblClick
        this.grid.ReadOnly = .f.
    ENDPROC
    PROCEDURE LostFocus
        this.grid.ReadOnly = .t.
    ENDPROC
ENDDEFINE


#16
huowang2022-09-08 11:27
感谢大家的指点,真心感谢
#17
huowang2022-09-08 11:34
以下是引用csyx在2022-9-7 21:22:38的发言:

开打调试器的事件跟踪可以看到,Before/AfterRowColChange事件是在click事件之前触发的,所以第一次会无效

有办法解决吗
#18
huowang2022-09-08 12:28
知道问题出在那了,走了弯路的
#19
csyx2022-09-08 13:12
设置一个计数器,避开首次双击时第二次触发的RowColChange事件,基本可用吧,没仔细测试各种情况
程序代码:
Create Cursor tt (F1 C(10), F2 C(10), F3 I)
Insert Into tt Values ("ABC", "123456", 101)
Clear
Insert Into tt Values ("DEF", "654321", 202)
Insert Into tt Values ("GHI", "456123", 303)
Go Top
Of = Createobject("form1")
Of.Show(1)

Define Class form1 As Form
    AllowOutput = .F.
    AutoCenter = .T.
    Add Object grid1 As myGrid
Enddefine

Define Class myGrid As Grid
    AllowCellSelection = .F.
    RowHeight = 22
    DblTimes = 0        && 用于判断是否首次双击
   
    Procedure DblClick
*!*    ? Textmerge('第 <<This.DblTimes>> 次双击')
        Local nWhere, oo
        Local aTemp[1]
*!*            nWhere = 0
*!*            This.GridHitTest(Mcol(0,3),Mrow(0,3), @ nWhere)
*!*            If nWhere != 3
*!*                Return
*!*            EndIf
        = AMouseObj(aTemp)
        oo = aTemp[1]
        If (Vartype(oo) == 'O') and (Lower(oo.BaseClass) $ ',textbox,combobox,checkbox,XXXX,')
            This.AllowCellSelection = .T.
            This.ReadOnly = .F.
            oo.SetFocus()
        Else
            This.AllowCellSelection = .F.
        EndIf
    Endproc
    Procedure AfterRowColChange(nColIndex)
*!*    ? 'After Event'
        If This.DblTimes > 1
            This.AllowCellSelection = .F.
        EndIf
        This.DblTimes = This.DblTimes + 1
    Endproc
EndDefine


[此贴子已经被作者于2022-9-8 13:18编辑过]

#20
schtg2022-09-09 07:03
上面吹版(14楼)、csyx版主(19楼),均能达到要求,学习啦,谢谢!
#21
liuxingang282022-09-21 11:36
表格的某些操作确实难倒了很多狐友,参考吹版和csyx版的发帖,我做了一下改进,看是否能达到楼主的满意:
程序代码:
CREATE CURSOR tt (F1 C(10), F2 C(10), F3 I)
INSERT INTO tt VALUES ("ABC", "123456", 101)
INSERT INTO tt VALUES ("DEF", "654321", 202)
INSERT INTO tt VALUES ("GHI", "456123", 303)
GO TOP
of = CREATEOBJECT("form1")
of.show(1)
RETURN

DEFINE CLASS form1 as Form
    ADD OBJECT grid1 as myGrid
    ADD OBJECT text1 as textbox WITH top = 210    && 增加了一个文本框控件,是为了验证活动控件为文本框时,双击表格行是否能切换到单元格
ENDDEFINE

DEFINE CLASS myGrid as Grid
    AllowCellSelection = .f.
    DblTimes = 0        && 用于判断是否首次双击
    PROCEDURE DblClick
        LOCAL oo as TextBox,aTemp[1]
        AMOUSEOBJ(aTemp)
        oo = aTemp[1]
        IF VARTYPE(oo) = 'O' AND oo.BaseClass = 'Textbox'
            THIS.AllowCellSelection = .t.
            THIS.ReadOnly = .f.
            oo.Parent.SelectOnEntry = .f.        && 首次双击时不选择单元格,保持与再次双击时效果一致
            oo.SetFocus
        ENDIF
    ENDPROC
    PROCEDURE AfterRowColChange(nColIndex)
        IF THIS.DblTimes != 0
            THIS.AllowCellSelection = .f.
        ENDIF
        THIS.DblTimes = 1  
    ENDPROC
    PROCEDURE When
        THIS.DblTimes = 0    && 表格获得焦点时,初始化双击标识
    ENDPROC
ENDDEFINE
#22
厨师王德榜2022-09-21 11:56
回复 21楼 liuxingang28
老司机出马果然非同凡响.
#23
liuxingang282022-09-21 12:03
回复 22楼 厨师王德榜
哈哈哈!估计关注VFP的都是老司机,胡子都白了,过几年要退休了
#24
huowang2022-10-14 16:24
谢谢大家
#25
schtg2022-10-15 05:38
回复 21楼 liuxingang28
@泉城飞狐,高!谢谢!
#26
a_bel2022-12-06 21:41
将焦点移出再设置回来,试试
1