简体   繁体   English

在 Listview 中显示对子项/单元格的 rect 焦点

[英]Display rect focus on subitems / cells in Listview

Like the title above, I am trying to display the focus box on the subitem / cell that is clicked.像上面的标题一样,我试图在单击的子项/单元格上显示焦点框。

To get the subitem / cell that is clicked I use the following code:要获取单击的子项/单元格,我使用以下代码:

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

At this point i have Row Index ( ClickedRowLV ) and Column Index ( ClickedColumnLV ) Now I'am trying show focus on that clicked subitem/cell.在这一点上,我有行索引( ClickedRowLV )和列索引( ClickedColumnLV )现在我正在尝试将焦点显示在单击的子项/单元格上。

How can I do that?我怎样才能做到这一点?

EDIT :编辑 :

Just to make sure that I didn't click the wrong item.只是为了确保我没有点击错误的项目。 So I want to have a focus rect or a sign if the sub-item is clicked.因此,如果单击子项,我希望有一个焦点矩形或一个标志。

Row must be full row select but at subitem /cell there is focus rect inside or outide.行必须是全行选择,但在子项/单元格中有焦点矩形内部或外部。 For example, please see the picture :例如,请看图片: 在此处输入图片说明

Not quite sure whether you mean something like:不太确定您的意思是否类似于:

SOQ60633347

If that is true, then you can handle the MouseDown event of the ListView control as follows:如果是这样,那么您可以按如下方式处理 ListView 控件的MouseDown事件:

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

Of course this won't work if the FullRowSelect property is enabled.当然,如果启用了FullRowSelect属性,这将不起作用。


Edit: Custom ListView编辑:自定义列表视图


Following up on your comment and update, I don't know any easy way to achieve that.跟进您的评论和更新,我不知道有什么简单的方法可以实现这一目标。 I think you need to create a custom ListView and override the relevant events as follows:我认为您需要创建一个自定义 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


Related有关的


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM