Исходный код в вопросе не работает, поскольку он создает New ToolTip
внутри OnMouseMove
.Я предполагаю, что метод ToolTip.Show
является асинхронным и, следовательно, функция завершается сразу после его вызова, уничтожая временный ToolTip
.Когда Show
начинает выполняться, объект больше не существует.
Решением будет создание постоянного ToolTip
объекта с помощью:
- a
ToolTip
элемента управленияна бланке;или - личное поле класса
ToolTip
(расположенное в методе класса Finalize
или Dispose
);или - a
Static
объекта внутри функции.
Также нет необходимости в GetItemAt()
, так как ListViewHitTestInfo
уже содержит ссылки на элемент и подэлемент.
Улучшение ответа Колина , вот мой код:
Private Sub ListView_MouseMove(sender As Object, e As MouseEventArgs) _
Handles MyList1.MouseMove
Static prevMousePos As Point = New Point(-1, -1)
Dim lv As ListView = TryCast(sender, ListView)
If lv Is Nothing Then _
Exit Sub
If prevMousePos = MousePosition Then _
Exit Sub ' to avoid annoying flickering
With lv.HitTest(lv.PointToClient(MousePosition))
If .SubItem IsNot Nothing AndAlso Not String.IsNullOrEmpty(.SubItem.Text) Then
'AndAlso .Item.SubItems.IndexOf(.SubItem) = 1
'...when a specific Column is needed
Static t As ToolTip = toolTip1 ' using a form's control
'Static t As New ToolTip() ' using a private variable
t.ShowAlways = True
t.UseFading = True
' To display at exact mouse position:
t.Show(.SubItem.Tag, .Item.ListView, _
.Item.ListView.PointToClient(MousePosition), 2000)
' To display beneath the list subitem:
t.Show(.SubItem.Tag, .Item.ListView, _
.SubItem.Bounds.Location + New Size(7, .SubItem.Bounds.Height + 1), 2000)
' To display beneath mouse cursor, as Windows does:
' (size is hardcoded in ugly manner because there is no easy way to find it)
t.Show(.SubItem.Tag, .Item.ListView, _
.Item.ListView.PointToClient(Cursor.Position + New Size(1, 20)), 2000)
End If
prevMousePos = MousePosition
End With
End Sub
Я сделал код как можно более общим, чтобы функцию можно было назначить нескольким ListView
с.