Как установить всплывающие подсказки на подэлементы ListView в .Net - PullRequest
4 голосов
/ 25 августа 2009

Я пытаюсь установить текст всплывающей подсказки для некоторых из моих подпунктов в моем элементе управления списком. Я не могу показать подсказку.

У кого-нибудь есть предложения?

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

Ответы [ 5 ]

9 голосов
/ 20 ноября 2010

Вы можете использовать событие 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, "");
    }
}
5 голосов
/ 11 марта 2010

При условии .NET 2.0 или более поздней версии вы также можете установить ListView.ShowItemToolTips в true. Если вам нужно настроить текст всплывающей подсказки для данного элемента, установите ListViewItem.ToolTipText на строку, которую хотите отобразить.

4 голосов
/ 26 февраля 2012

Исходный код в вопросе не работает, поскольку он создает New ToolTip внутри OnMouseMove.Я предполагаю, что метод ToolTip.Show является асинхронным и, следовательно, функция завершается сразу после его вызова, уничтожая временный ToolTip.Когда Show начинает выполняться, объект больше не существует.

Решением будет создание постоянного ToolTip объекта с помощью:

  1. a ToolTip элемента управленияна бланке;или
  2. личное поле класса ToolTip (расположенное в методе класса Finalize или Dispose);или
  3. 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 с.

4 голосов
/ 25 августа 2009

ObjectListView (оболочка с открытым исходным кодом вокруг .NET WinForms ListView) имеет встроенную поддержку всплывающих подсказок для ячеек (и, да, он работает с VB). Вы слушаете событие CellToolTip и можете делать такие вещи (которые, по общему признанию, чрезмерны):

alt text

Если вы не хотите использовать ObjectListView, вам нужно создать подкласс ListView, прослушать WM_NOTIFY сообщения, а затем внутри них ответить на TTN_GETDISPINFO уведомления, аналогично следующему:

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 голосов
/ 10 августа 2010

Если вы установите ShowItemTooltips для элемента управления ListView в режиме «подробности» и больше ничего не делаете, элемент управления ListView автоматически предоставит всплывающие подсказки для элементов и подпунктов, которые превышают ширину их столбцов. Это работает, даже если для свойства FullRowSelect установлено значение true. Если ToolTipText был установлен для ListViewItem и FullRowSelect имеет значение true, тогда всплывающая подсказка будет отображаться для всей строки; это тот случай, когда всплывающие подсказки не будут отображаться для подпунктов.

...