J
Jason
Hello all,
I have been looking around Google Groups trying to find out how to
enable background images with System.Windows.Forms.ListView only to
discover most people are having a lot of difficulty. After several hours
hunting around with Lutz Roeder's .NET Reflector I have created an
inherited class (source code at bottom) to cause the usually ignored
BackgroundImage property of the ListView to become enabled. I noticed
that when the ListView had UserPaint enabled it would automatically draw
the background but then I'd need to manually draw the items. So I just
caught the WM_ERASEBKGND message, enabled UserPaint for the background
stage, then disabled UserPaint for the foreground stage. No WinAPI was
required. At the moment the background is always aligned top-left and
tiled to fill the ListView but this suits my needs so I'll leave the
tiling adjustment until another day. By the way, I only use ListViews in
Report/Detail view mode so I haven't tested it with other views.
Hopefully this will be useful to many other fellow programmers.
The remaining problem is that an empty list shows the full background
image but as ListViewItems are added the rows are always drawn with a
solid BackColor hiding the background image behind the text. Again, this
is not a major problem for my application but it would be nice to make
the row BackColor transparent so the background image shows like a
watermark behind any text. Setting the ListView or the ListViewItem's
BackColor to Color.Transparent is rejected with an exception. If I use
MyBase.SetStyle(ControlStyles.SupportsTransparentBackColor, True) in my
extended class's constructor I can set the BackColor to Transparent but
it still draws as white. From what I've discovered about Microsoft's
ListView implementation is that I will probably need to catch WM_NOTIFY
messages of type NM_CUSTOMDRAW and either set the BackColor
appropriately there or draw each row's background manually. I have no
experience with the CustomDraw service and there are so many options
that I don't know where to start. Perhaps someone who is more familiar
with this aspect of Common Controls can provide some assistance.
Thank you in advance,
- Jason
''' CODE BEGINS
'Just drop a ListViewWithBackground onto a form and set the
'BackgroundImage property during the form's Load event.
Public Class ListViewWithBackground
Inherits System.Windows.Forms.ListView
Private Const WM_ERASEBKGND As Int32 = &H14
Protected Overrides Sub WndProc(ByRef m As
System.Windows.Forms.Message)
Select Case m.Msg
Case WM_ERASEBKGND
Dim styleUserPaint As Boolean =
Me.GetStyle(ControlStyles.UserPaint)
Dim styleAllPainting As Boolean =
Me.GetStyle(ControlStyles.AllPaintingInWmPaint)
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, False)
MyBase.WndProc(m)
Me.SetStyle(ControlStyles.UserPaint, styleUserPaint)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint,
styleAllPainting)
Case Else
MyBase.WndProc(m)
End Select
End Sub
End Class
''' CODE ENDS
I have been looking around Google Groups trying to find out how to
enable background images with System.Windows.Forms.ListView only to
discover most people are having a lot of difficulty. After several hours
hunting around with Lutz Roeder's .NET Reflector I have created an
inherited class (source code at bottom) to cause the usually ignored
BackgroundImage property of the ListView to become enabled. I noticed
that when the ListView had UserPaint enabled it would automatically draw
the background but then I'd need to manually draw the items. So I just
caught the WM_ERASEBKGND message, enabled UserPaint for the background
stage, then disabled UserPaint for the foreground stage. No WinAPI was
required. At the moment the background is always aligned top-left and
tiled to fill the ListView but this suits my needs so I'll leave the
tiling adjustment until another day. By the way, I only use ListViews in
Report/Detail view mode so I haven't tested it with other views.
Hopefully this will be useful to many other fellow programmers.
The remaining problem is that an empty list shows the full background
image but as ListViewItems are added the rows are always drawn with a
solid BackColor hiding the background image behind the text. Again, this
is not a major problem for my application but it would be nice to make
the row BackColor transparent so the background image shows like a
watermark behind any text. Setting the ListView or the ListViewItem's
BackColor to Color.Transparent is rejected with an exception. If I use
MyBase.SetStyle(ControlStyles.SupportsTransparentBackColor, True) in my
extended class's constructor I can set the BackColor to Transparent but
it still draws as white. From what I've discovered about Microsoft's
ListView implementation is that I will probably need to catch WM_NOTIFY
messages of type NM_CUSTOMDRAW and either set the BackColor
appropriately there or draw each row's background manually. I have no
experience with the CustomDraw service and there are so many options
that I don't know where to start. Perhaps someone who is more familiar
with this aspect of Common Controls can provide some assistance.
Thank you in advance,
- Jason
''' CODE BEGINS
'Just drop a ListViewWithBackground onto a form and set the
'BackgroundImage property during the form's Load event.
Public Class ListViewWithBackground
Inherits System.Windows.Forms.ListView
Private Const WM_ERASEBKGND As Int32 = &H14
Protected Overrides Sub WndProc(ByRef m As
System.Windows.Forms.Message)
Select Case m.Msg
Case WM_ERASEBKGND
Dim styleUserPaint As Boolean =
Me.GetStyle(ControlStyles.UserPaint)
Dim styleAllPainting As Boolean =
Me.GetStyle(ControlStyles.AllPaintingInWmPaint)
Me.SetStyle(ControlStyles.UserPaint, True)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, False)
MyBase.WndProc(m)
Me.SetStyle(ControlStyles.UserPaint, styleUserPaint)
Me.SetStyle(ControlStyles.AllPaintingInWmPaint,
styleAllPainting)
Case Else
MyBase.WndProc(m)
End Select
End Sub
End Class
''' CODE ENDS