2

I have a scroll-able form which I would like to print entirely.

I have already tried using this code to print it:

    Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click
    Me.PrintForm.PrintAction = Printing.PrintAction.PrintToPreview
    Me.PrintForm.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.Scrollable) 
End Sub

And the result isn't accurate at all.

To demonstrate my issue, here are some photos:

This is the result I want (Of course I want it to ALSO print all of the scroll-able content)

As you can see, This image contains all of the width I need for the image, but because it's a print screen image, it doesn't contain the scroll-able area which I would like to have in my printable version of the form. Good result

and this is what I get from my code:

As you can see here, I only get about 60% of the form width, and 50% of the height, and clearly, I don't get the scroll-able area.

Bad result

I don't really care about the quality I just want it to print the whole form including the Scroll-able area.

kfirba
  • 5,231
  • 14
  • 41
  • 70

5 Answers5

3

In this line:

PrintForm1.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.Scrollable)

It looks like PrintOption.Scrollable is only going to work, if you have a scrollable form. You have a scrollable control here (probably a Panel), inside a form. In this case its area will not be expanded onto the printer. Compare:

Scrollable control:

enter image description here

prints as:

enter image description here

Scrollable form:

enter image description here

prints as:

enter image description here

According to this official answer from Microsoft, capturing a scrollable control is not possible with PrintForm. If you use a PrintDocument and some custom coding, you can do it for simple cases, such as a scrollable TextBox. In your case you may need even more custom coding to be done. Handling PrintDocument1.PrintPage looks like the best place to start, if you are up to it.

Victor Zakharov
  • 25,801
  • 18
  • 85
  • 151
1

Based on what you're showing... it looks like the scrollable area is a container like a Panel. If that's the case, printing the form isn't the problem, it's printing the scrollable control.

Have a look at this project to create a bitmap from a control: http://www.codeproject.com/Articles/35734/Print-a-WinForms-User-Control

EDIT: On second thought, I don't think the code at that link addresses the actual scrolling problem either.

I think you're going to need to do one of two things: 1) Temporarily resize the panel large enough that the scrollbars disappear then resize it back 2) Build a control (perhaps a "Printable Version" form) that doesn't have nested scrollable elements and gracefully deals with stuff like pagination.

Option #2 might sound like a lot of work, but I think you could pretty quickly do something like: create a new panel, clone each control you want printed and add it to the panel (resizing as necessary to avoid scrolling), print the panel, then dispose of the panel.

Gojira
  • 2,941
  • 2
  • 21
  • 30
  • But can I also print some area from the form itself? It's late at night here, so I will check it tomorrow's morning ;) Hope I'm gonna find my solution there :) I will keep you updated once I try it tomorrow – kfirba Mar 14 '13 at 21:49
  • Well, it is going to be tricky combining the form bitmap / panel bitmaps. What you might consider is to dock a single panel that fills the form completely, then add child controls to that panel and print the single panel. Or - if you have the freedom to do this: make a "printable" version of the form that better takes into account things like pagination (a single long image is going to look junky when printed across multiple pages). – Gojira Mar 14 '13 at 22:04
  • I tried your link that you gave me, I have no idea if it's work since it's automatically sends the report to print. How do I make it display a preview before printing? – kfirba Mar 15 '13 at 09:00
1

I Think your answer is in the article
All you need is to reference to FormPrinting library (or import the source to your solution).

Private Sub btnPrint_Click(object sender, EventArgs e)
        {
            var fp = new FormPrinting.FormPrinting(this);                
            fp.Print();
        }

will do the printing job.
I have tested the library, having no problems with scrollable contents like images and ....

Mohsen Heydari
  • 7,256
  • 4
  • 31
  • 46
  • I couldn't find a VB.NET code source, and moreover, I haven't understood how to use it although I read the article – kfirba Mar 20 '13 at 09:06
  • For start(to test the functionality) just add the c# project (in the article) to your solution. Add reference to that project. the library is called "FormPrinting" then using the source i mentioned in my answer will do the rest. Test the functionality and inform me pal. – Mohsen Heydari Mar 20 '13 at 10:18
  • Well, I don't have any C# compiler on my PC so that's going to be a problem :s – kfirba Mar 20 '13 at 14:04
  • You don't have Visual Studio? – Mohsen Heydari Mar 20 '13 at 14:08
  • If you go to the article and download the Download demo project then inside the ziped file you will find FormPrinting.dll http://www.codeproject.com/KB/printing/PrintingFormReport/Demo.zip – Mohsen Heydari Mar 20 '13 at 14:12
  • I found it, no idea how to use it to be honest – kfirba Mar 20 '13 at 18:09
  • Add reference to FormPrinting.dll from your project. the library is then using the source i mentioned in my answer (btnPrint_Click) will do the rest – Mohsen Heydari Mar 20 '13 at 19:19
  • How do I add a reference? and what if I wanna print a tableLayoutPanel only? I just supply another argument than "this"/"me"? – kfirba Mar 20 '13 at 21:25
  • right click on your project ...> add reference...> find the FormPrinting.dll on your hard disk, first test the library then we will proceed – Mohsen Heydari Mar 20 '13 at 21:31
  • I have tested it, and it's almost accurate. Now, I get all of the content that I want, but the spacing between each row is HUGE and there are some words that it's cutting down and he doesn't show some field but it's really close – kfirba Mar 21 '13 at 06:10
  • There is a Demo project on the article, the demo project have a Form called DemoForm having a button called "PrintMe", follow the click event of the button ... there are useful settings when printing like Portrait or Lanscape printing, setting report title and ... may come in handy – Mohsen Heydari Mar 21 '13 at 07:43
0

Check for the MSDN Forum of the code here the code like this

  1. In the Toolbox, click the Visual Basic PowerPacks tab and then drag the PrintForm component onto the form.

  2. The PrintForm component will be added to the component tray.

  3. In the Properties window, set the PrintAction property to PrintToPrinter.

Add the following code in the appropriate event handler (for example, in the Click event handler for a Print Button).

PrintForm1.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.Scrollable)

and here got the same question as your and have been answer.

Kasnady
  • 2,249
  • 3
  • 25
  • 34
0

I had a similar problem I was able to solve without any additional libraries or extensions. It is simple with the DrawToBitmap method available on most Forms controls.

    Dim ctrlColl As ControlCollection
    Dim i As Integer = 0

    ' Get collection of controls
    ctrlColl = Me.Controls

    ' create bitmap array
    Dim Bitmaps(ctrlColl.Count - 1) As Bitmap

    ' remove controls you have hidden before printing
    For Each ctrl As Control In ctrlColl
        If Not ctrl.Visible Then
            ctrlColl.Remove(ctrl)
        End If
    Next

    ' Loop through controls
    For Each ctrl As Control In ctrlColl
        ' create bitmap from control.DrawToBitmap
        Bitmaps(i) = New Bitmap(ctrl.Width, ctrl.Height)
        ctrl.DrawToBitmap(Bitmaps(i), ctrl.ClientRectangle)
        i = i + 1
    Next

    ' Print each bitmap in array
    i = 0
    For Each bmp As Bitmap In Bitmaps
        e.Graphics.DrawImage(bmp, New Point(ctrlColl(i).Location.X, ctrlColl(i).Location.Y))
        i = i + 1
    Next

End Sub
bstiffler582
  • 102
  • 11