我正在尝试为listview控件中的某些子项设置工具提示文本。我无法获得显示的工具提示。
有人有任何建议吗?
Private _timer As Timer
Private Sub Timer()
If _timer Is Nothing Then
_timer = New Timer
_timer.Interval = 500
AddHandler _timer.Tick, AddressOf TimerTick
_timer.Start()
End If
End Sub
Private Sub TimerTick(ByVal sender As Object, ByVal e As EventArgs)
_timer.Enabled = False
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
If Not _timer.Enabled Then
Dim item = Me.HitTest(e.X, e.Y)
If Not item Is Nothing AndAlso Not item.SubItem Is Nothing Then
If item.SubItem.Text = "" Then
Dim tip = New ToolTip
Dim p = item.SubItem.Bounds
tip.ToolTipTitle = "Status"
tip.ShowAlways = True
tip.Show("FOO", Me, e.X, e.Y, 1000)
_timer.Enabled = True
End If
End If
End If
MyBase.OnMouseMove(e)
End Sub
答案 0 :(得分:8)
您可以使用MouseMove
事件:
private void listview1_MouseMove(object sender, MouseEventargs e)
{
ListViewItem item = listview1.GetItemAt(e.X, e.Y);
ListViewHitTestInfo info = listview1.HitTest(e.X, e.Y);
if((item != null) && (info.SubItem != null))
{
toolTip1.SetToolTip(listview1, info.SubItem.Text);
}
else
{
toolTip1.SetToolTip(listview1, "");
}
}
答案 1 :(得分:5)
假设使用.NET 2.0或更高版本,您还可以将ListView.ShowItemToolTips设置为true
。如果您需要自定义给定项目的工具提示文本,请将ListViewItem.ToolTipText设置为您想要显示的字符串。
答案 2 :(得分:4)
ObjectListView(围绕.NET WinForms ListView的开源包装)内置了对单元工具提示的支持(是的,它确实可以与VB一起使用)。你在听CellToolTip
事件,你可以做这样的事情(这无疑是过分的):
如果您不想使用ObjectListView,则需要继承ListView,监听WM_NOTIFY
消息,然后在这些消息中,以类似于此的方式响应TTN_GETDISPINFO
通知:< / p>
case TTN_GETDISPINFO:
ListViewHitTestInfo info = this.HitTest(this.PointToClient(Cursor.Position));
if (info.Item != null && info.SubItem != null) {
// Call some method of your own to get the tooltip you want
String tip = this.GetCellToolTip(info.Item, info.SubItem);
if (!String.IsNullOrEmpty(tip)) {
NativeMethods.TOOLTIPTEXT ttt = (NativeMethods.TOOLTIPTEXT)m.GetLParam(typeof(NativeMethods.TOOLTIPTEXT));
ttt.lpszText = tip;
if (this.RightToLeft == RightToLeft.Yes)
ttt.uFlags |= 4;
Marshal.StructureToPtr(ttt, m.LParam, false);
return; // do not do normal processing
}
}
break;
显然,这是C#,而不是VB,但你明白了。
答案 3 :(得分:3)
如果在“详细信息”模式下为ListView控件设置ShowItemTooltips而不执行任何其他操作,则ListView控件将自动为超出其列宽的项目和子项提供工具提示。即使FullRowSelect属性设置为true,这也会起作用。如果为ListViewItem设置了ToolTipText并且FullRowSelect为true,则将显示整行的工具提示;这就是不会为子项目显示工具提示的情况。
答案 4 :(得分:3)
问题中的原始代码无效,因为它会在New ToolTip
内创建OnMouseMove
。我想ToolTip.Show
方法是异步的,因此函数在调用后会立即退出,从而破坏临时ToolTip
。当Show
执行时,该对象不再存在。
解决方案是通过以下方式创建一个持久的ToolTip
对象。
ToolTip
控制;或ToolTip
类字段(位于该类的Finalize
或Dispose
方法中);或Static
对象。此外,由于GetItemAt()
已包含项目和子项目参考,因此无需ListViewHitTestInfo
。
改进Colin的答案,这是我的代码:
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
。