I've got a DateTimePicker which I 'dynamically' assign the Paint-Event, unfortunately as long as this Event is assigned neither the text nor the DropDown-Button are rendered (but are working).
I've written a component which takes another control and draws something on it
Public Sub New(Byval parent As Control)
Me._parent = parent
Me._setStyle = Me._parent.GetType().GetMethod("SetStyle", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
Me._setStyle.Invoke(Me._parent, New Object() {ControlStyles.UserPaint, True})
Me._setStyle.Invoke(Me._parent, New Object() {ControlStyles.OptimizedDoubleBuffer, True})
AddHandler Me._parent.Paint, AddressOf RemotePaintHandler
End Sub
Private Sub RemotePaintHandler(ByVal sender As Object, ByVal e As PaintEventArgs)
'draw something here'
End Sub
At disposing of the component I'm removing the handler and resetting the styles. But as long as the Handler is assigned the DateTimePicker renders like a normal Textbox without content, but the button is working and I can also enter values. If I've overwritten the OnPaint() method I'd simply call MyBase.OnPaint() or similar...but this is an eventhandler...I'm totally clueless here right now.
I figured something out. As it seems the UserPaint happens within the underlying control and not in the DateTimePicker itself, 'causing it to render faulty. This will happen as long as the Style UserPaint is set.
One workaround is to let it render correct within the Paint-Event...which is not that easy I fear, but possible:
We remove the Handler and the Style for the Paint-Event, refresh the control ('causing it to render correctly), then drawing our things on top of the newly rendered control, and re-adding the Style and the Paint-Eventhandler. The downside is, that everything we draw disappears while somebody is entering some information (it's there if you use the calendar box), and might not come back until some_one_ refreshes the control. So this seems to be an ugly hack then a real workaround or even a solution[1].
Though, I've only tested this with a DateTimePicker, and have no clue if this also works with other controls (but it seems so).
[1] I mean, I know the solution, rewriting the Control within the Framework...
The
DateTimePicker
have noOnPaint
method to draw itself. It's in fact a wrapper around the windows controlSysDateTimePick32
, so when you set UserPaint = true, the control (real one) no longer draws itself and there will be only your drawings.You can inherit from
DateTimePicker
, overrideWndProc
, respond toWM_PAINT
message by executingPaint event
subscribers. Here an example:then use this new control instead of the regular
DateTimePicker
& subscribe to it's Paint2 event to draw what you need:(you don't need to set
UserPaint = True
, you're capturingWM_PAINT
anyway)hope this helps,