Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

vb.net - Listview - Multi column - Change selection color for the whole row

I would like to change selection color in a ListView, from a default (blue). I can not adapt any code that I found to my needs.

Here is the code that is closest.

  If e.Item.Selected = True Then
        e.Graphics.FillRectangle(New SolidBrush(Color.Gray), e.Bounds)
        TextRenderer.DrawText(e.Graphics, e.Item.Text, New Font(ListView2.Font, Nothing), New Point(e.Bounds.Left + 3, e.Bounds.Top + 2), Color.White)
    Else
        e.DrawDefault = True
    End If

The main problem is e.Item.Text part. It doesn't work for multi column listview. Here is the result.

Before selection : enter image description here

...and after : enter image description here

Is it possible to preserve values from other columns and still have full row selection?

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The thing to keep in mind with an OwnerDraw Listview is that there are 2 events to respond to (or override if you are subclassing) if the control is Details View: DrawColumnHeader and DrawSubItem.

DrawItem would be used when the control is using a different View and there are no SubItems to draw.

Since SubItems(0) is the same as Item.Text, you can use DrawSubItem to draw the item and subitem text. I cannot tell where that snippet is located, but this will work:

Private Sub lv1_DrawSubItem(sender As Object, 
       e As DrawListViewSubItemEventArgs) Handles lv1.DrawSubItem

    ' use sender instead of a hardcodes control ref so 
    ' you can paste this to another LV
    Dim myLV As ListView = CType(sender, ListView)

    If e.ItemIndex > 0 AndAlso e.Item.Selected Then
        Using br As New SolidBrush(Color.Gray)
            e.Graphics.FillRectangle(br, e.Bounds)
        End Using

        Using fnt As New Font(myLV .Font, Nothing)
        ' use e.SubItem.Text
            TextRenderer.DrawText(e.Graphics, e.SubItem.Text,
                          fnt,
                          New Point(e.Bounds.Left + 3, e.Bounds.Top + 2),
                          Color.White)
        End Using     ' dispose!
    Else
        e.DrawDefault = True
    End If

End Sub

It would appear that you may be using the correct event, but by usingItem.Text rather than e.SubItem.Text the Item text will be also be drawn for all SubItems (DrawSubItem will be called as many times as there are subitems).

Note that I also wrapped the Font in a Using block to dispose of it. Using LimeGreen, the result:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...