VB.net中DataGridView控件的CellMouseClick事件以及ContextMenuStrip问题

时间:2022-01-20 18:05:16
背景:
DataGridView的每一行的行右键菜单项的enable和visable都会有所不同。

做法:
1)先初期化时每一行设置一个固定的ContextMenuStrip。
DataGridView1.Rows(rowIndex).Cells(1).ContextMenuStrip = Me.ContextMenuStrip1

2)然后在DataGridView的CellMouseClick事件中,重新设置菜单项的enable值和visable值。

    Private Sub DataGridView1_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles dgvDocumentList.CellMouseClick

        If e.Button = MouseButtons.Left Then
            Return
        End If

        If e.ColumnIndex = 1 AndAlso e.RowIndex >= 0 Then

           ' 第一行的菜单设置
            If  e.RowIndex  = 1 Then
                 ContextMenuStrip1.Items.Item("xxxxx").Visible = False
            End If
        End If

    End Sub


现象:
可能因为事先设置了ContextMenuStrip,右键操作根本不执行DataGridView1_CellMouseClick事件。
试着在DataGridView1_CellMouseClick里设置完ContextMenuStrip再改值。
发现最开始点击两次才出菜单,然后点几次后又不执行DataGridView1_CellMouseClick事件了。

8 个解决方案

#1


[为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了,
引用 1 楼 yangliu0512 的回复:
为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。, 快捷菜单应该有个Opening事件吧, 可在这里改变项目状态.,
引用 2 楼 菖蒲芭芭的回复:
Quote: 引用 1 楼 yangliu0512 的回复:

为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。

我做过类似的,就是在这事件里设置,你试过只设置整个dgv的不一行一行设置的吗?应该不会出这个问题的。,
引用 4 楼 yangliu0512 的回复:
Quote: 引用 2 楼 菖蒲芭芭的回复:
Quote: 引用 1 楼 yangliu0512 的回复:

为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。

我做过类似的,就是在这事件里设置,你试过只设置整个dgv的不一行一行设置的吗?应该不会出这个问题的。


现在的业务是每一行出来菜单都不太一样,需要重新设置enable和visable值。请问如何实现。,
引用 5 楼 flagiris 的回复:
Quote: 引用 4 楼 yangliu0512 的回复:

Quote: 引用 2 楼 菖蒲芭芭的回复:
Quote: 引用 1 楼 yangliu0512 的回复:

为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。

我做过类似的,就是在这事件里设置,你试过只设置整个dgv的不一行一行设置的吗?应该不会出这个问题的。


现在的业务是每一行出来菜单都不太一样,需要重新设置enable和visable值。请问如何实现。

给你举个栗子吧:

Private Sub DGV_List_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DGV_List.CellMouseClick
        If e.Button = MouseButtons.Right Then
            If e.RowIndex >= 0 Then
                DGV_List.Rows(e.RowIndex).Selected = True
                DGV_List.CurrentCell = DGV_List.Rows(e.RowIndex).Cells(1)
                ContextMenu_DGV.Show(DGV_List, e.Location)
                ContextMenu_DGV.Show(Cursor.Position)
                '下面的代码可以根据e参数来获取DGV_List的行或列的信息来设置IF条件
                'If DGV_List.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = 0 Then
                ContextMenu_DGV.Items.Item(0).Visible = False
                ContextMenu_DGV.Items.Item(1).Enabled = False
                'End If
            End If
        End If
    End Sub
, 做的时候只需要一个ContextMenu的实例,把所有可能出现的菜单项全列出来,具体到某一行的时候,把不要的隐藏或者Enable为False, 应该在DataGridView1_CellClick事件里处理
用e.colindex判断当前列,然后再激活对应事件。

也可以把所有右键菜单都做在一个里面,然后判断点击所在列,隐藏显示相关内容。]

#1


[为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了,
引用 1 楼 yangliu0512 的回复:
为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。, 快捷菜单应该有个Opening事件吧, 可在这里改变项目状态.,
引用 2 楼 菖蒲芭芭的回复:
Quote: 引用 1 楼 yangliu0512 的回复:

为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。

我做过类似的,就是在这事件里设置,你试过只设置整个dgv的不一行一行设置的吗?应该不会出这个问题的。,
引用 4 楼 yangliu0512 的回复:
Quote: 引用 2 楼 菖蒲芭芭的回复:
Quote: 引用 1 楼 yangliu0512 的回复:

为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。

我做过类似的,就是在这事件里设置,你试过只设置整个dgv的不一行一行设置的吗?应该不会出这个问题的。


现在的业务是每一行出来菜单都不太一样,需要重新设置enable和visable值。请问如何实现。,
引用 5 楼 flagiris 的回复:
Quote: 引用 4 楼 yangliu0512 的回复:

Quote: 引用 2 楼 菖蒲芭芭的回复:
Quote: 引用 1 楼 yangliu0512 的回复:

为什么要每一行去单独设置contextmenustrip?整个datagridview设置好contextmenustrip不就好了吗?窗体载入的时候设置或者 直接 在属性面板设置好,肯定不会出你说的问题了


整个datagridview设置好contextmenustrip是没有问题的。
但是每一行的菜单项的enable和visable值还是要重新设置的吧,
问题就是设置enable和visable值在哪个事件里做?
在CellMouseClick做就是有上述问题。

我做过类似的,就是在这事件里设置,你试过只设置整个dgv的不一行一行设置的吗?应该不会出这个问题的。


现在的业务是每一行出来菜单都不太一样,需要重新设置enable和visable值。请问如何实现。

给你举个栗子吧:

Private Sub DGV_List_CellMouseClick(sender As Object, e As DataGridViewCellMouseEventArgs) Handles DGV_List.CellMouseClick
        If e.Button = MouseButtons.Right Then
            If e.RowIndex >= 0 Then
                DGV_List.Rows(e.RowIndex).Selected = True
                DGV_List.CurrentCell = DGV_List.Rows(e.RowIndex).Cells(1)
                ContextMenu_DGV.Show(DGV_List, e.Location)
                ContextMenu_DGV.Show(Cursor.Position)
                '下面的代码可以根据e参数来获取DGV_List的行或列的信息来设置IF条件
                'If DGV_List.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = 0 Then
                ContextMenu_DGV.Items.Item(0).Visible = False
                ContextMenu_DGV.Items.Item(1).Enabled = False
                'End If
            End If
        End If
    End Sub
, 做的时候只需要一个ContextMenu的实例,把所有可能出现的菜单项全列出来,具体到某一行的时候,把不要的隐藏或者Enable为False, 应该在DataGridView1_CellClick事件里处理
用e.colindex判断当前列,然后再激活对应事件。

也可以把所有右键菜单都做在一个里面,然后判断点击所在列,隐藏显示相关内容。]