【问题标题】:MouseDown event conflicts with CellMouseEnter eventMouseDown 事件与 CellMouseEnter 事件冲突
【发布时间】:2018-08-29 09:06:39
【问题描述】:

我有两个事件可以单独运行,但一个会阻止另一个。

底部有完整的代码和图形用户界面

目标:
我正在尝试将 TreeNode 拖放到 DataGridView 中,并选择/突出显示我悬停的单元格。

突出显示单元格的事件:

 Public Sub DataGridView1_CellMouseEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellMouseEnter
    Try
        Me.DataGridView1.CurrentCell = Me.DataGridView1(DataGridView1.Columns(e.ColumnIndex).DisplayIndex, DataGridView1.Rows(e.RowIndex).Index)
    Catch
    End Try
 End Sub

拖放事件:

  • TreeView1_MouseDown - 设置布尔值以确定鼠标是否按下
  • TreeView1_MouseMove - 获取要拖动的项目
  • DataGridView1_DragEnter - 拖动时的样式
  • DataGridView1_Dragdrop - 将项目拖放到数据网格视图中

我的问题是(任何)MouseDown 事件会阻止 CellMouseEnter 事件。
我在表单的其他地方尝试了 mousedown-ing,然后将鼠标悬停在 DataGridView 上,我的 CellMouseEnter 事件不起作用。

结果是该项目被放入在 MouseDown 之前选择的单元格中(从技术上讲,此单元格仍然被选中 b/c CellMouseEnter 不会将选定的单元格更新为悬停的单元格)

所以在我看来,我需要构建一个类似于CellMouseEnter 的自定义事件,它不会被 MouseDown 阻止,但我什至不知道从哪里开始。我尝试了 Peek Definition,但找不到CellMouseEnter 的实际方法,只是 Public Event CellMouseEnter As DataGridViewCellEventHandler.

有没有更好的办法?

这里是我的拖放事件:

Private Sub TreeView1_MouseDown(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseDown
    move_item = True
End Sub

Private Sub TreeView1_MouseMove(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseMove
    If move_item Then
        On Error GoTo quit
        Dim item2move As New Label
        item2move.Text = TreeView1.SelectedNode.Text
        item2move.DoDragDrop(item2move.Text, DragDropEffects.Copy)
        Debug.Print(TreeView1.SelectedNode.Text)
    End If
    move_item = False

退出: 退出子 结束子

Private Sub DataGridView1_DragEnter(sender As Object, e As DragEventArgs) Handles DataGridView1.DragEnter
    If (e.Data.GetDataPresent(DataFormats.Text)) Then
        e.Effect = DragDropEffects.Copy
    Else
        e.Effect = DragDropEffects.None
    End If
End Sub

Private Sub DataGridView1_DragDrop(sender As Object, e As DragEventArgs) Handles DataGridView1.DragDrop
    With DataGridView1
        Dim Col As Integer = .CurrentCell.ColumnIndex
        Dim row As Integer = .CurrentCell.RowIndex
        .Item(Col, row).Value = e.Data.GetDataPresent(DataFormats.Text)
    End With
End Sub

完整代码:注意一些示例 JSON 在最后的评论中,将其放在 RichtextBox - rtb_inputjson

Public Class Form1
    Dim move_item As Boolean

    'Add some rows to the treemap on load
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        For i = 1 To 20
            DataGridView1.Rows.Add()
        Next
    End Sub

    'JSON to treemap
    Private Sub btn_jsontotreemap_Click(sender As Object, e As EventArgs) Handles btn_jsontotreemap.Click
        Try
            Dim json As String = rtb_inputjson.Text
            Dim obj As New JObject
            obj = JObject.Parse(json)
            TreeView1.Nodes.Clear()
            Dim parent As TreeNode = Json2Tree(obj)
            parent.Text = "Root Object"
            TreeView1.Nodes.Add(parent)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

    Private Function Json2Tree(ByVal obj As JObject) As TreeNode
        'creates the parent node
        Dim parent As TreeNode = New TreeNode()

        'loop through the obj all token should be pair <key, value>
        For Each token In obj
            parent.Text = token.Key.ToString()
            'create child node
            Dim child As TreeNode = New TreeNode()
            child.Text = token.Key.ToString()

            'self call :) 
            If token.Value.Type.ToString() = "Object" Then
                Dim o As JObject = CType(token.Value, JObject)
                child = Json2Tree(o)
                child.Text = token.Key.ToString()
                parent.Nodes.Add(child)

                'but if it is an array...
            ElseIf token.Value.Type.ToString() = "Array" Then
                Dim ix As Integer = -1
                For Each itm In token.Value

                    'check each item of the array to see if they are objects or arrays
                    If itm.Type.ToString() = "Object" Then
                        Dim objTN As TreeNode = New TreeNode()
                        ix += 1
                        Dim o As JObject = CType(itm, JObject)

                        'self call :)
                        objTN = Json2Tree(o)
                        objTN.Text = token.Key.ToString() & "[" & ix & "]"
                        child.Nodes.Add(objTN)
                    ElseIf itm.Type.ToString() = "Array" Then
                        ix += 1
                        Dim dataArray As TreeNode = New TreeNode()
                        For Each i In itm
                            dataArray.Text = token.Key.ToString() & "[" & ix & "]"
                            dataArray.Nodes.Add(i.ToString())
                        Next
                        child.Nodes.Add(dataArray)
                    Else
                        child.Nodes.Add(itm.ToString())
                    End If
                Next
                parent.Nodes.Add(child)
            Else
                If token.Value.ToString() = "" Then child.Nodes.Add("N/A") Else child.Nodes.Add(token.Value.ToString())
                parent.Nodes.Add(child)
            End If
        Next
        Return parent
    End Function


    'drag & drop to datagridview
    Private Sub TreeView1_MouseDown(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseDown
        move_item = True
    End Sub

    Private Sub TreeView1_MouseMove(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseMove
        If move_item Then
            On Error GoTo quit
            Dim item2move As New Label
            item2move.Text = TreeView1.SelectedNode.Text
            item2move.DoDragDrop(item2move.Text, DragDropEffects.Copy)
            Debug.Print(TreeView1.SelectedNode.Text)
        End If
        move_item = False
quit:
        Exit Sub
    End Sub

    Public Sub DataGridView1_CellMouseEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellMouseEnter
        Debug.Print("CellMouseEnter event raised")
        Try
            Me.DataGridView1.CurrentCell = Me.DataGridView1(DataGridView1.Columns(e.ColumnIndex).DisplayIndex, DataGridView1.Rows(e.RowIndex).Index)
        Catch
        End Try
    End Sub

    Private Sub DataGridView1_DragDrop(sender As Object, e As DragEventArgs) Handles DataGridView1.DragDrop

        With DataGridView1
            Dim Col As Integer = .CurrentCell.ColumnIndex
            Dim row As Integer = .CurrentCell.RowIndex
            .Item(Col, row).Value = e.Data.GetDataPresent(DataFormats.Text)
        End With
    End Sub

    Private Sub DataGridView1_DragEnter(sender As Object, e As DragEventArgs) Handles DataGridView1.DragEnter
        If (e.Data.GetDataPresent(DataFormats.Text)) Then
            e.Effect = DragDropEffects.Copy
        Else
            e.Effect = DragDropEffects.None
        End If
    End Sub
End Class

文本框的示例 JSON:

{
   "data":[
      {
         "symbol":"A",
         "name":"Agilent Technologies Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"2"
      },
      {
         "symbol":"AA",
         "name":"Alcoa Corporation",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"12042"
      },
      {
         "symbol":"AABA",
         "name":"Altaba Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"7653"
      },
      {
         "symbol":"AAC",
         "name":"AAC Holdings Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"9169"
      },
      {
         "symbol":"AADR",
         "name":"AdvisorShares Dorsey Wright ADR",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"et",
         "iexId":"5"
      },
      {
         "symbol":"AAL",
         "name":"American Airlines Group Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"8148"
      },
      {
         "symbol":"AAMC",
         "name":"Altisource Asset Management Corp Com",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"7760"
      },
      {
         "symbol":"AAME",
         "name":"Atlantic American Corporation",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"7"
      },
      {
         "symbol":"AAN",
         "name":"Aaron's Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"8"
      },
      {
         "symbol":"AAOI",
         "name":"Applied Optoelectronics Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"7790"
      },
      {
         "symbol":"AAON",
         "name":"AAON Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"9"
      },
      {
         "symbol":"AAP",
         "name":"Advance Auto Parts Inc W/I",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"10"
      },
      {
         "symbol":"AAPL",
         "name":"Apple Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"11"
      },
      {
         "symbol":"AAT",
         "name":"American Assets Trust Inc.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"12"
      },
      {
         "symbol":"AAU",
         "name":"Almaden Minerals Ltd.",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"13"
      },
      {
         "symbol":"AAV",
         "name":"Advantage Oil & Gas Ltd",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"14"
      },
      {
         "symbol":"AAWW",
         "name":"Atlas Air Worldwide Holdings",
         "date":"2018-03-19",
         "isEnabled":true,
         "type":"cs",
         "iexId":"15"
      }
   ]
}

控件及其名称:

【问题讨论】:

  • MouseDown 在任何鼠标按钮按下/单击控件时触发..当鼠标悬停在控件上时会发生MouseEnter....所以,除非你有一些奇怪的代码...如果使用你相同的代码,我能重现这个问题吗?
  • 是的。但是你必须填充树视图,我的是从文本框中完成的
  • @zach raiyan -好的,我已经添加了完整的代码
  • @zackraiyan 他们在不同的控件上工作 MouseDown 在 treeview1 控件上,cellmouseenter 在 datagridview1 控件中的单元格上
  • 您错过了DataGridView DragOver 事件。从那里,您可以计算可以转换为单元坐标的DataGridView.HitTestInfoCellMouseEnterCellMouseMove 不必干扰拖放事件,因此它们不会在这种情况下做出反应。

标签: vb.net winforms events datagridview mouseevent


【解决方案1】:

我最终使用 HittestInfo 来获取正确的单元格,而不是使用 CellMouseEnter 选择单元格,我决定取消选择序列开头的所有单元格。我还添加了一个悬停来选择正确的树视图项。

Private Sub TreeView1_MouseDown(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseDown
    move_item = True
End Sub

Private Sub TreeView1_MouseMove(sender As Object, e As MouseEventArgs) Handles TreeView1.MouseMove

    If move_item Then
        On Error GoTo quit
        'Deselect all cells in datagridview
        DataGridView1.ClearSelection()
        DataGridView1.CurrentCell = Nothing

        'Begin Drag/drop
        Dim item2move As New Label
        item2move.Text = TreeView1.SelectedNode.Text
        item2move.DoDragDrop(item2move.Text, DragDropEffects.Copy)

    End If
    move_item = False
quit:
    Exit Sub
End Sub


Private Sub DataGridView1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragEnter
    If (e.Data.GetDataPresent(DataFormats.Text)) Then
        e.Effect = DragDropEffects.Copy
    Else
        e.Effect = DragDropEffects.None
    End If
End Sub


Private Sub DataGridView1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles DataGridView1.DragDrop
    Try
        Dim clickedcell As DataGridViewCell
        Dim ptscreen As New Point(e.X, e.Y)
        Dim ptclient = DataGridView1.PointToClient(ptscreen)

        Dim hit As DataGridView.HitTestInfo = DataGridView1.HitTest(ptclient.X, ptclient.Y)
        clickedcell = DataGridView1.Rows(hit.RowIndex).Cells(hit.ColumnIndex)
        DataGridView1.Item(clickedcell.ColumnIndex, clickedcell.RowIndex).Value = e.Data.GetData(DataFormats.Text).ToString

    Catch
    End Try
End Sub

Private Sub TreeView1_NodeMouseHover(sender As Object, e As TreeNodeMouseHoverEventArgs) Handles TreeView1.NodeMouseHover
    TreeView1.SelectedNode = e.Node
End Sub

【讨论】:

  • 我将发布一个示例代码,向您展示我在 cmets 中的意思。试一试。
【解决方案2】:

使用DragOver() 事件,您的优势在于,当Drop() 操作生效时,用户可以获得单元格的视觉反馈,因为鼠标悬停的单元格变为活动状态并跟随鼠标移动.

您还可以验证鼠标指针下的单元格是否可以接收拖放,如果没有,则避免选择它。

Private Sub dataGridView1_DragEnter(sender As Object, e As DragEventArgs)
    e.Effect = If(e.Data.GetDataPresent(DataFormats.Text) = True,
                  DragDropEffects.Copy,
                  DragDropEffects.None)

Private Sub dataGridView1_DragDrop(sender As Object, e As DragEventArgs)
    'Check whether the current Cell supports this Drop()
    DataGridView1.CurrentCell.Value = e.Data.GetDataPresent(DataFormats.Text).ToString()
End Sub

Private Sub dataGridView1_DragOver(sender As Object, e As DragEventArgs)
    Dim ClientAreaLocation As Point = dataGridView1.PointToClient(New Point(e.X, e.Y))
    Dim CellPosition As DataGridView.HitTestInfo = dataGridView1.HitTest(ClientAreaLocation.X, ClientAreaLocation.Y)

    If CellPosition.ColumnIndex > -1 AndAlso CellPosition.RowIndex > -1 Then
        'Enable if this Cell supports this Drop()
        dataGridView1.CurrentCell = dataGridView1(CellPosition.ColumnIndex, CellPosition.RowIndex)
    End If
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 1970-01-01
    相关资源
    最近更新 更多