【问题标题】:Find listview column index using HitTestInfo使用 HitTestInfo 查找列表视图列索引
【发布时间】:2013-03-26 15:48:48
【问题描述】:

当我使用此代码右键单击列表视图项时,我正在寻找列的索引:

Private Sub Source_lvArticles_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Source_lvArticles.MouseDown
    If e.Button = System.Windows.Forms.MouseButtons.Right Then
        Sources_RightClickedCol = 0

        Dim info As ListViewHitTestInfo = Source_lvArticles.HitTest(e.X, e.Y)
        Sources_RightClickedCol = info.Location
    End If
End Sub

我能够找到我正在右键单击的项目的文本 (info.Subitem.Text),我只是找不到它的列索引...

【问题讨论】:

    标签: .net vb.net listview hittest


    【解决方案1】:

    有一种非常更简单的方法可以让“列”被点击:

    Private Function GetSubItemIndexAt(x As Integer, y As Integer) As Integer
        ' get HitTextinfo for X,Y
        Dim ht As ListViewHitTestInfo = myLV.HitTest(x, y)
    
        If ht.Item IsNot Nothing Then
            ' use built in method to get the index
            Return ht.Item.SubItems.IndexOf(ht.SubItem)
        End If
    
        Return -1           ' (semi) universal not found indicator
    
    End Function
    

    请记住,索引 0 将引用 ItemLabel 区域。

    唯一需要注意的是HitTest 仅适用于有实际项目的情况。如果单击非项目区域,例如下面的空白区域,则该 XY 将导致没有项目可以使用。

    【讨论】:

      【解决方案2】:

      不幸的是,对于 Alex 提供的上述代码,如果一行中有多个子项包含相同的文本值,那么它会选择最左边的第一个列索引。更好的方法是复制下面的函数,它只是使用鼠标指针 X 值并将其与列右值进行比较,其中 X 超过了我们在循环计数上的整数:

      Private Function GetColumnIndex(ByVal lvw As ListView, ByVal MouseX As _
      Integer) As Integer
      
          Dim result As Integer = 0
      
          'Get the right and width pixel values of all the columns 
          Dim ColW As New List(Of Integer)
          Dim Index As Integer = 0
      
      
          For Each col As ColumnHeader In lvw.Columns
              ColW.Add(col.Width)
              Dim X As Integer = 0
              For i As Integer = 0 To ColW.Count - 1
                  X += ColW(i)
              Next
      
              'Once you have the rightmost values of the columns 
              'just work out where X falls in between
      
              If MouseX <= X Then
                  result = Index
                  Exit For
              End If
      
              Index += 1
      
          Next
      
          Return result
      End Function
      

      【讨论】:

        【解决方案3】:

        对于那些想知道我做了什么来计算我的列索引的人......这不是很优雅,但它有效。

        Private Sub Source_lvArticles_MouseDown(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Source_lvArticles.MouseDown
            If e.Button = System.Windows.Forms.MouseButtons.Right Then
                Sources_RightClickedCol = 0
        
                Dim info As ListViewHitTestInfo = Source_lvArticles.HitTest(e.X, e.Y)
                Dim SubItem As String = info.SubItem.Text
        
                For Each item As ListViewItem In Source_lvArticles.Items
                    Dim i As Integer = 1
                    Dim found As Boolean = False
                    For Each s As ListViewItem.ListViewSubItem In item.SubItems
                        If s.Text = SubItem Then
                            Sources_RightClickedCol = i
                            found = True
                            Exit For
                        End If
                        i += 1
                    Next
                    If found Then Exit For
                Next
            End If
        End Sub
        

        这样做是遍历列表视图中每一行的每个子项并保持列索引 (i) 的计数。它将当前子项的文本与 HitTest 检测到的文本进行比较

        【讨论】:

          【解决方案4】:

          您还可以在填充列表视图时使用 subitem.tag 属性存储有关列的信息,然后稍后使用 hittest.(e.X, e.Y).SubItem.tag 检索此信息。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-03-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-07-31
            • 1970-01-01
            相关资源
            最近更新 更多