Is there a way to change the color of the listview gridlines (black would be nice)? I have Gridlines = True, but the color is so faint that they cannot be seen (for example on Win XP with the default Blue theme). You can only see them on a highlighted item. (If I change the backcolor of the LV to a funky color, I can see them, but I want to keep the default color of "Window" (white when Win XP default them is used).
Probably have to do OwnerDrawing or subclass the listview and intercept the pain message but to determine when its painting the gridlines would be hard.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
If you subclass, it should be very similar from any solutions you can find in VB 6 as Im sure you know. Perhaps there is something in the lParam or wParam paramteres of the WM_PAINT message call that specifies the gridlines are being drawn. Have you tried looking at Spy++ messages of a demo app to see?
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
does the listview gridlines still have that scrolling bug where half your text gets a strikeout look and grid lines don't draw correctly for half of them?
Last time I tried using gridlines, I found this to be the case, and stopped using them.
Rob, perhaps you can confirm if the issue no longer exists in Vista (don't have a Vista box around ATM), but I just tested a .NET 3.5 app on XP, and the issue is still there. You need to have enough items to get a scrollbar, then all you do is scroll to produce the bug.
It has to do with the repainting. If you drag the scrollbar manually, it will fix, but the issue happens anytime you scroll with the arrows.
No, I had also tried it with more items after I posted to make sure. Under Vista and a new blank 3.5 vb project I can not duplicate your image issue. Using the arrow keys, mouse wheel, or manually dragging the thumb scrollbar, its all good except as originally noted with the bottom focus rectangle issue.
Edit, I added a second column too populated with test items and still its good.
VB/Office Guru™ (AKA: Gangsta Yoda™ ®)
I dont answer coding questions via PM. Please post a thread in the appropriate forum.
Hey guys, I was going back and forth on whether or not to use gridlines as I was also experiencing the scroll issue Matt mentioned. I decided to live with it. But back to the original question about changing the color, is owner drawing / subclassing the only way to go here, and if so, how difficult would it be to implement? (An example would be nice as I am not an expert in the whole owner-drawing / subclassing arena.)
Bruce, I got around to getting you a working sample of custom drawing a listview in details view where you can customize the gridline color.
It took a little trial and error, as the listview can be a bit odd when it comes to custom drawing its items. However I think this has all the same standard functionality, while still giving you the extra settings you need.
The new properties exposed by the class are:
GridLines - shadows the original property, has same result, however when true custom draws the grid GridLineColor - color in which to draw the grid lines ItemHighlightColor - color to use to highlight selected items ItemNotFocusedHighlightColor - color to use to highlight selected items when listview is not focused (and HideSelection set to false) UseDefaultGridLines - Set to true to bypass custom gridlines and use original ones
I didn't fully test in all scenarios (as the listview is pretty robust) but give it a go, and if you need some help let me know.
All you need to do is paste it into its own class file, and then compile the project, you can then add the new listview class from the toolbox to your form.
Code:
Public Class ListViewEx
Inherits System.Windows.Forms.ListView
Private _gridLines As Boolean = False
Private _useDefaultGridLines As Boolean = False
Private _gridLineColor As Color = Color.Black
Private _itemHighlightColor As Color = Color.FromKnownColor(KnownColor.Highlight)
Private _itemNotFocusedHighlighColor As Color = Color.FromKnownColor(KnownColor.MenuBar)
Public Property GridLineColor() As Color
Get
Return _gridLineColor
End Get
Set(ByVal value As Color)
If value <> _gridLineColor Then
_gridLineColor = value
If _gridLines Then
Me.Invalidate()
End If
End If
End Set
End Property
Public Property ItemHighlightColor() As Color
Get
Return _itemHighlightColor
End Get
Set(ByVal value As Color)
If value <> _itemHighlightColor Then
_itemHighlightColor = value
Me.Invalidate()
End If
End Set
End Property
Public Property ItemNotFocusedHighlighColor() As Color
Get
Return _itemNotFocusedHighlighColor
End Get
Set(ByVal value As Color)
If value <> _itemNotFocusedHighlighColor Then
_itemNotFocusedHighlighColor = value
Me.Invalidate()
End If
End Set
End Property
Private ReadOnly Property DrawCustomGridLines() As Boolean
Get
Return (_gridLines And Not _useDefaultGridLines)
End Get
End Property
Public Shadows Property GridLines() As Boolean
Get
Return _gridLines
End Get
Set(ByVal value As Boolean)
_gridLines = value
End Set
End Property
Public Property UseDefaultGridLines() As Boolean
Get
Return _useDefaultGridLines
End Get
Set(ByVal value As Boolean)
If _useDefaultGridLines <> value Then
_useDefaultGridLines = value
End If
MyBase.GridLines = value
MyBase.OwnerDraw = Not value
End Set
End Property
Protected Overrides Sub OnDrawColumnHeader(ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs)
e.DrawDefault = True
MyBase.OnDrawColumnHeader(e)
End Sub
Protected Overrides Sub OnLostFocus(ByVal e As System.EventArgs)
For Each selectedIndex As Integer In MyBase.SelectedIndices
MyBase.RedrawItems(selectedIndex, selectedIndex, False)
Next
MyBase.OnLostFocus(e)
End Sub
Protected Overrides Sub OnDrawSubItem(ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs)
Dim drawAsDefault As Boolean = False
Dim highlightBounds As Rectangle = Nothing
Dim highlightBrush As SolidBrush = Nothing
'FIRST DETERMINE THE COLOR
If e.Item.Selected Then
If MyBase.Focused Then
highlightBrush = New SolidBrush(_itemHighlightColor)
ElseIf HideSelection Then
drawAsDefault = True
Else
highlightBrush = New SolidBrush(_itemNotFocusedHighlighColor)
End If
Else
drawAsDefault = True
End If
If drawAsDefault Then
e.DrawBackground()
Else
'NEXT DETERMINE THE BOUNDS IN WHICH TO DRAW THE BACKGROUND
If FullRowSelect Then
highlightBounds = e.Bounds
Else
highlightBounds = e.Item.GetBounds(ItemBoundsPortion.Label)
End If
'ONLY DRAW HIGHLIGHT IN 1 OF 2 CASES
'CASE 1 - FULL ROW SELECT (AND DRAWING ANY ITEM)
'CASE 2 - NOT FULL ROW SELECT (AND DRAWING 1ST ITEM)
If FullRowSelect Then
e.Graphics.FillRectangle(highlightBrush, highlightBounds)
ElseIf e.ColumnIndex = 0 Then
e.Graphics.FillRectangle(highlightBrush, highlightBounds)
Else
e.DrawBackground()
End If
End If
e.DrawText()
If _gridLines Then
e.Graphics.DrawRectangle(New Pen(_gridLineColor), e.Bounds)
End If
If FullRowSelect Then
e.DrawFocusRectangle(e.Item.GetBounds(ItemBoundsPortion.Entire))
Else
e.DrawFocusRectangle(e.Item.GetBounds(ItemBoundsPortion.Label))
End If
MyBase.OnDrawSubItem(e)
End Sub
End Class
also, sorry for lack of comments, but i didn't really have time to put them in. You should be able to tell what is going on though, its not super complicated.
Can you please describe how to use your code? A quick example of a listview and your class together would be a great help. I am still new in VB. Thank you.
Can you please describe how to use your code? A quick example of a listview and your class together would be a great help. I am still new in VB. Thank you.
Do you know how to use the regular listview?
My code is nothing more than an extended class of the listview that comes with Visual Studio.
It works exactly the same way as the standard listview, except it has the 5 additional properties I outlined in my above post that you can set to get the extended behavior.
Thanks for replying me quickly.
I normally use listview by place it from the tool box. Then I add items,, etc. How can I make a listview from you code to the design screen? And then can I set properties from the property window? Thanks.
You add a new class file to your project. When it asks for a name for the class, name it ListViewEx (just so you don't have to rename it later if you leave it class1.vb)
After you do that, it will bring up the code window for that class. Erase the 2 lines of the empty class definition that is generated and paste in my entire code from above which is the entire extended class.
After that all you need to do is build your project, and ListViewEx will be in the toolbox.
Hi Matt, I tested your code and found out it only display the horizontal gridlines. Also it does not display gridlines with items that are empty. Is it what you designed or I am using it incorrectly. Thanks.
Thats sounds right since this workaround meant custom drawing the actual items with borders around them. So if there is no item, there is no border, so no grid.
The solution would be to not have any listviewitems that don't have the same number of subitems as the listview has columns. You could add empty string subitems, which should make the grid draw.
Yes it works in 2010. How can you possibly have alternate rows with different border colours? The borders are shared by the adjoining cells!
As the 6-dimensional mathematics professor said to the brain surgeon, "It ain't Rocket Science!"
Reviews: "dunfiddlin likes his DataTables" - jmcilhinney
Please be aware that whilst I will read private messages (one day!) I am unlikely to reply to anything that does not contain offers of cash, fame or marriage!