That method only prints what is in view for the most part.
What you should be doing is using a internal bitmap that holds all of that, use the canvas of the bitmap as you would the screen.
The OnPaint event for the form, you simply paint that bitmap to the form.
when you print or save, you can simply use the internal bitmap.
The other way around that is to create a procedure that receives a Canvas as a parameter and with that, you do the same as you would on your screen. The difference is, you can send the canvas of a bitmap, the form or a printer canvas and all should behave the same.