Vb.net 在Framework 4.0中的ListView第一行上显示工具提示
我有一个WinForm应用程序,是用VB.Net在Framework 2.0中开发的,它在所有ListView对象上使用事件MouseMove在ListView的第一行上显示工具提示文本-据我所知,如果没有第三方工具,ColumnHeader上不可能有工具提示 问题是,自从我将应用程序转换为Framework4.0后,这个“技巧”就不起作用了,工具提示也不再显示 有人知道一种解决方案,或者更好的方法,在ListView列标题上显示工具提示吗 以下是我的代码片段:Vb.net 在Framework 4.0中的ListView第一行上显示工具提示,vb.net,winforms,listview,columnheader,Vb.net,Winforms,Listview,Columnheader,我有一个WinForm应用程序,是用VB.Net在Framework 2.0中开发的,它在所有ListView对象上使用事件MouseMove在ListView的第一行上显示工具提示文本-据我所知,如果没有第三方工具,ColumnHeader上不可能有工具提示 问题是,自从我将应用程序转换为Framework4.0后,这个“技巧”就不起作用了,工具提示也不再显示 有人知道一种解决方案,或者更好的方法,在ListView列标题上显示工具提示吗 以下是我的代码片段: Private Sub Show
Private Sub ShowTooltip(ByVal sender As Object, ByVal e As MouseEventArgs)
Handles myListView.MouseMove
Dim iColumn As System.Int32 = FindListViewColumnHeader(e.X, e.Y)
If Me.myListView.Columns.Count > 0 AndAlso iColumn >= 0 AndAlso
iColumn <= Me.myListView.Columns.Count - 1 Then
Me.myToolTip.Active = True
Me.myToolTip.UseAnimation = True
Me.myToolTip.UseFading = True
Me.myToolTip.AutomaticDelay = 10000
Me.myToolTip.AutoPopDelay = 10000
Me.myToolTip.InitialDelay = 0
Me.myToolTip.ReshowDelay = 2000
Dim sTooltipText As System.String = SomeText(...)
If sTooltipText <> DirectCast(Me.myToolTip.Tag, System.String) Then
Me.myToolTip.Tag = sTooltipText
Me.myToolTip.SetToolTip(Me.myListView, sTooltipText)
End If
Else
Me.myToolTip.Active = False
End If
End Sub
Protected Overridable Function FindListViewColumnHeader(ByVal X As System.Int32,
ByVal Y As System.Int32) As System.Int32
If Y > 20 And Y < 40 Then
Dim iCount As System.Int32
Dim iLeft As System.Int32
For iCount = 0 To myListView.Columns.Count - 1
iLeft = iLeft + myListView.Columns(iCount).Width
If X <= iLeft Then
Return iCount
Exit For
End If
Next
Return iCount
Else
Return -1
End If
End Function
而myListView是
Protected WithEvents myListView As System.Windows.Forms.ListView
请注意,如问题所述:
,
ShowItemToolTips
已设置为True。您可以获取标题列的句柄并将其子类化:
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As Win32WndProc) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function CallWindowProc(lpPrevWndFunc As IntPtr, hWnd As IntPtr, Msg As UInteger, wParam As Integer, lParam As Integer) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function
Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const GWL_WNDPROC As Integer = -4
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_MOUSEMOVE As Integer = &H200
Private oldWndProc As IntPtr = IntPtr.Zero
Private newWndProc As Win32WndProc = Nothing
Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
'hWnd is the window you want to subclass...,
'create a new delegate for the new wndproc
newWndProc = New Win32WndProc(AddressOf MyWndProc)
'subclass
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
End Sub
Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Select Case Msg
Case WM_LBUTTONDOWN
'The lower 2 bytes of lParam are the x coordinate
'and the higher 2 bytes the y.
ToolTip1.Show("My tooltip", ListView1, lParam And &HFFFF, (lParam >> 16) And &HFF, 2000)
Exit Select
Case Else
Exit Select
End Select
Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
End Function
为了方便起见,我使用了WM_LBUTTONDOWN
事件。您可以使用WM_MOUSEMOVE
事件检查鼠标所在的列等。。。并显示工具提示
子类化的代码:ColumnHeader不会生成MouseMove或MouseHover类型的事件,因此即使LV也不知道鼠标位于头部分上。事实上,如果您在对象浏览器中查看,它的唯一事件是
Disposed
。工具提示提供程序不适用于ColumnHeader
,因此我想知道什么是ToolTipText()
?ListViewItems具有该属性,但不具有标题<代码>lsRecords是个谜too@Plutonix我想代码是可疑的。什么是lsRecords?看起来应该是myListView。我更正了代码片段,lsRecords是个错误。我的问题是,在Framework4.0中,工具提示也不适用于ListViewItems。LVI有自己的内置工具提示文本属性。我看不出它是如何工作的:DirectCast(Me.myListView.Columns(iColumn),ColumnHeader.ToolTipText()
不会编译,因为ColumnHeader
上没有ToolTipText
提供的代码不会在NET2.0中的ColumnHeader上显示工具提示。当鼠标移到某个项目或子项目上时,它会立即显示,但当鼠标移到标题上时,它会立即消失。您的解决方案非常有效,谢谢!我只是做了一个小的修正来正确读取x坐标:lParam和&HFFFF。
<DllImport("user32.dll", SetLastError:=True)> _
Private Shared Function SetWindowLong(ByVal hWnd As IntPtr, ByVal nIndex As Integer, ByVal newProc As Win32WndProc) As IntPtr
End Function
<DllImport("user32.dll")> _
Private Shared Function CallWindowProc(lpPrevWndFunc As IntPtr, hWnd As IntPtr, Msg As UInteger, wParam As Integer, lParam As Integer) As Integer
End Function
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As IntPtr
End Function
Private Delegate Function Win32WndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const GWL_WNDPROC As Integer = -4
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_MOUSEMOVE As Integer = &H200
Private oldWndProc As IntPtr = IntPtr.Zero
Private newWndProc As Win32WndProc = Nothing
Private Sub SubclassHWnd(ByVal hWnd As IntPtr)
'hWnd is the window you want to subclass...,
'create a new delegate for the new wndproc
newWndProc = New Win32WndProc(AddressOf MyWndProc)
'subclass
oldWndProc = SetWindowLong(hWnd, GWL_WNDPROC, newWndProc)
End Sub
Private Function MyWndProc(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Select Case Msg
Case WM_LBUTTONDOWN
'The lower 2 bytes of lParam are the x coordinate
'and the higher 2 bytes the y.
ToolTip1.Show("My tooltip", ListView1, lParam And &HFFFF, (lParam >> 16) And &HFF, 2000)
Exit Select
Case Else
Exit Select
End Select
Return CallWindowProc(oldWndProc, hWnd, Msg, wParam, lParam)
End Function
'LVM_GETHEADER = &H101F
Dim hwndHeader As IntPtr = SendMessage(ListView1.Handle, &H101F, 0, 0)
SubclassHWnd(hwndHeader)