Отобразить прямоугольный фокус на подэлементах / ячейках в Listview - PullRequest
0 голосов
/ 11 марта 2020

Как и в заголовке выше, я пытаюсь отобразить поле фокуса на выбранном элементе / ячейке.

Чтобы получить выбранный элемент / ячейку, я использую следующий код:

Private Sub LV_MouseClick(sender As Object, e As MouseEventArgs) Handles LV.MouseClick
    Info = LV.HitTest(e.Location)
    ClickedColumnLV = Info.Item.SubItems.IndexOf(Info.SubItem)
    ClickedRowLV = Info.Item.Index
    If e.Button = MouseButtons.Right Then
        If LV.FocusedItem.Bounds.Contains(e.Location) Then
            CMenu.Show(Cursor.Position)
        End If
    End If
End Sub

На данный момент у меня есть индекс строки (ClickedRowLV) и индекс столбца (ClickedColumnLV). Теперь я пытаюсь показать фокус на выбранном подпункте / ячейке.

Как мне это сделать? ?

РЕДАКТИРОВАТЬ:

Просто чтобы убедиться, что я не нажал не тот элемент. Поэтому я хочу иметь прямоугольник фокуса или знак при щелчке по подпункту.

Строка должна быть полностью выделена, но в подэлементе / ячейке есть прямоугольник фокуса внутри или снаружи. Например, см. Рисунок: enter image description here

1 Ответ

0 голосов
/ 11 марта 2020

Не совсем уверен, имеете ли вы в виду что-то вроде:

SOQ60633347

Если это так, то вы можете обработать событие MouseDown объекта ListView. управляйте следующим образом:

Private Sub LV_MouseDown(sender As Object, e As MouseEventArgs) Handles LV.MouseDown
    Dim selColor = SystemColors.Highlight
    Dim item = LV.Items.Cast(Of ListViewItem).
        Where(Function(x) x.BackColor.Equals(selColor) OrElse
        x.SubItems.Cast(Of ListViewItem.ListViewSubItem).
        Any(Function(y) y.BackColor.Equals(selColor))).FirstOrDefault

    If item IsNot Nothing Then
        item.BackColor = SystemColors.Window
        item.ForeColor = SystemColors.WindowText

        For Each subItem In item.SubItems.Cast(Of ListViewItem.ListViewSubItem)
            subItem.BackColor = SystemColors.Window
            subItem.ForeColor = SystemColors.WindowText
        Next
    End If

    Dim ht = LV.HitTest(e.Location)

    If ht.SubItem IsNot Nothing Then
        ht.Item.UseItemStyleForSubItems = False
        ht.SubItem.BackColor = selColor
        ht.SubItem.ForeColor = SystemColors.Window        
    End If
End Sub

Конечно, это не будет работать, если свойство FullRowSelect включено.


Редактировать: Custom ListView


После ваших комментариев и обновлений я не знаю простого способа добиться этого. Я думаю, вам нужно создать собственный ListView и переопределить соответствующие события следующим образом:

Imports System.Windows.Forms
Imports System.Drawing
Imports System.ComponentModel

<DesignerCategory("Code")>
Public Class ListViewEx
    Inherits ListView

    Private ht As ListViewHitTestInfo

    Sub New()
        MyBase.New
        DoubleBuffered = True
        OwnerDraw = True
        FullRowSelect = True
    End Sub

    Public Property DrawFocusRectangle As Boolean = True

    Protected Overrides Sub OnDrawColumnHeader(e As DrawListViewColumnHeaderEventArgs)
        e.DrawDefault = True
    End Sub

    Protected Overrides Sub OnDrawItem(e As DrawListViewItemEventArgs)
        If View = View.Details Then Return

        If e.Item.Selected Then
            e.Graphics.FillRectangle(Brushes.LightSteelBlue, e.Bounds)
            e.DrawFocusRectangle()
        Else
            e.DrawBackground()
        End If

        e.DrawText()
    End Sub

    Protected Overrides Sub OnDrawSubItem(e As DrawListViewSubItemEventArgs)
        Using sf As New StringFormat With {
                            .Alignment = StringAlignment.Near,
                            .LineAlignment = StringAlignment.Center,
                            .Trimming = StringTrimming.EllipsisCharacter,
                            .FormatFlags = StringFormatFlags.NoWrap
                        },
                        br = New SolidBrush(e.SubItem.ForeColor)

            Select Case e.Header.TextAlign
                Case HorizontalAlignment.Center
                    sf.Alignment = StringAlignment.Center
                Case HorizontalAlignment.Right
                    sf.Alignment = StringAlignment.Far
            End Select

            If e.Item.Selected Then
                If e.ColumnIndex = 0 OrElse FullRowSelect Then
                    e.Graphics.FillRectangle(Brushes.LightSteelBlue, e.Bounds)
                End If
            Else
                e.DrawBackground()
            End If
            e.Graphics.DrawString(e.SubItem.Text, e.SubItem.Font, br, e.Bounds, sf)
        End Using

        'Here you go...
        If DrawFocusRectangle AndAlso ht IsNot Nothing AndAlso
            e.Item.Focused AndAlso e.SubItem Is ht.SubItem Then
            Using pn As New Pen(Color.Orange, 2)
                Dim r As New Rectangle(e.Bounds.X,
                                       e.Bounds.Y,
                                       e.Header.Width - 1,
                                       e.Bounds.Height - 1)

                e.Graphics.DrawRectangle(pn, r)

                'or just draw focus rectangle ...
                'ControlPaint.DrawFocusRectangle(e.Graphics, r)
            End Using
        End If
    End Sub

    Protected Overrides Sub OnMouseDown(e As MouseEventArgs)
        MyBase.OnMouseDown(e)

        ht = HitTest(e.Location)
        Invalidate()
    End Sub

    Protected Overrides Sub OnColumnWidthChanged(e As ColumnWidthChangedEventArgs)
        MyBase.OnColumnWidthChanged(e)
        Invalidate()
    End Sub

End Class

SOQ60633347B


Связанные


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...