Introduction
I wanted to customize the ListView
control without going for the full owner draw approach. So custom draw was the obvious solution.
Background
I have done this sort of thing in ATL/WTL before, so I knew that I needed the parent of the control to reflect the notification message (.NET does by default). I also needed to handle the reflected notification message OCM_NOTIFY
to perform my custom drawing. I stumbled across an interesting article by Georgi Atanasov, Customizing the header control in a ListView. So with the help of this article, I created my own sample ListView control that basically changes the font of the item text and sets the background color to that beautiful aqua color!!
Using the code
The EventListView.cs contains the ListView
derived control and implements the ICustomDraw
interface. The ICustomDraw
interface contains the various stages of custom drawing that can occur:
int OnPrePaint(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
int OnPostPaint(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
int OnPreErase(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
int OnPostErase(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
int OnItemPrePaint(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
int OnItemPostPaint(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
int OnItemPreErase(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
int OnItemPostErase(int idCtrl, ref Win32.NMCUSTOMDRAW nmcd);
It also contains a property Handle
which is used to test that the reflect message really is for this control.
IntPtr Handel { get; }
EventListView
class creates an object of type CustomDrawHandler
and overrides the WndProc
procedure and passes the message to this CustomDrawHandler
.
protected override void WndProc(ref Message m)
{
m_custDrawHandler.HandleReflectedCustDrawMessage(ref m);
if (!m_custDrawHandler.MessageHandled)
base.WndProc (ref m);
}
The HandleReflectedCustDrawMessage
function checks to see if we have an OCM_NOTIFY
message and that the message code is for CustomDraw
. It then checks the draw stage and calls back onto the interface that was passed to its constructor, i.e., the ListView
derived control. The EventListView.OnPrePaint
function returns CDRF_NOTIFYITEMDRAW
which causes the OnItemPrePaint
function to be called. The OnItemPrePaint
changes the background color of the item and draws the item text in an Arial font.
History
This is the first version of the custom draw in C#. Please feel free to email me with any comments or suggestions.