在 Framework 4.0 的 ListView 第一行显示工具提示
Show ToolTips on ListView first row in Framework 4.0
我有一个在 Framework 2.0 中开发的 WinForm 应用程序 VB.Net 它在所有 ListView 对象上使用事件 MouseMove 以在第一行显示工具提示文本ListViews - 据我所知,如果没有第三方工具,就不可能在 ColumnHeader 上有工具提示。
问题是 自从我将应用程序转换为 Framework 4.0 后,此 "trick" 无法正常工作 并且不再显示工具提示。
有谁知道在 ListView ColumnHeaders 上显示工具提示的解决方案或者更好的方法吗?
这是我的代码片段:
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
注意:我的工具提示是
Friend WithEvents myToolTip As System.Windows.Forms.ToolTip
而 myListView 是
Protected WithEvents myListView As System.Windows.Forms.ListView
请注意,如问题中所建议的:
How to set tooltip for a ListviewItem、ShowItemToolTips
已设置为 True。
您可以获得 header 列的句柄并将其子类化:
<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
要对 header 进行子类化,请使用:
'LVM_GETHEADER = &H101F
Dim hwndHeader As IntPtr = SendMessage(ListView1.Handle, &H101F, 0, 0)
SubclassHWnd(hwndHeader)
为了方便起见,我使用了 WM_LBUTTONDOWN
事件。您可以使用 WM_MOUSEMOVE
事件并检查鼠标在哪一列等...并显示工具提示
我有一个在 Framework 2.0 中开发的 WinForm 应用程序 VB.Net 它在所有 ListView 对象上使用事件 MouseMove 以在第一行显示工具提示文本ListViews - 据我所知,如果没有第三方工具,就不可能在 ColumnHeader 上有工具提示。
问题是 自从我将应用程序转换为 Framework 4.0 后,此 "trick" 无法正常工作 并且不再显示工具提示。
有谁知道在 ListView ColumnHeaders 上显示工具提示的解决方案或者更好的方法吗?
这是我的代码片段:
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
注意:我的工具提示是
Friend WithEvents myToolTip As System.Windows.Forms.ToolTip
而 myListView 是
Protected WithEvents myListView As System.Windows.Forms.ListView
请注意,如问题中所建议的:
How to set tooltip for a ListviewItem、ShowItemToolTips
已设置为 True。
您可以获得 header 列的句柄并将其子类化:
<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
要对 header 进行子类化,请使用:
'LVM_GETHEADER = &H101F
Dim hwndHeader As IntPtr = SendMessage(ListView1.Handle, &H101F, 0, 0)
SubclassHWnd(hwndHeader)
为了方便起见,我使用了 WM_LBUTTONDOWN
事件。您可以使用 WM_MOUSEMOVE
事件并检查鼠标在哪一列等...并显示工具提示