Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Can't get a range of pages to print 3

Status
Not open for further replies.

BigSassy

Programmer
Aug 19, 2005
6
US
Hi. I'm embarrased that I'm having so much trouble with something so simple, but here it goes.

In my code I have a PrintDialog that allows the user to select a page range to print (the AllowSomePages property is set to true), but when a range is selected (ex: pages 2-3) in the dialog it still print all the pages in the document. I've been following the API documentation as well as articles/tutorials online but I still can't get it to work. Multiple copies print fine. Print to File works fine. Just the page range doesn't work.

I've tried manually setting the ToPage and FromPage members in the PrintDocument's PrinterSettings and DefaultPrinterSettings members as well as in the PrintDialog's PrinterSettings member. I've also set the MinimumPages and MaximumPages in each one with no success.

Here's some test code I've been trying to solve the problem with (...well the latest version anyway). The code is on a WinForm with one button (Button2). I really don't know what I'm doing wrong. Any help at solving my problem would be very appreciated.

**************************************
**WinForms code**
**************************************

Public PageCount As Integer
WithEvents Doc As New PrintDocument

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

Dim Diag As New PrintDialog

Diag.Document = Doc

Diag.AllowSomePages = True
Diag.PrinterSettings.MinimumPage = 1
Diag.PrinterSettings.MaximumPage = 3
Diag.PrinterSettings.FromPage = 1
Diag.PrinterSettings.ToPage = 3

If Diag.ShowDialog() = DialogResult.OK Then
PageCount = 1
Doc.Print()
End If
End Sub

Private Sub PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles Doc.PrintPage

Dim f As New Font(FontFamily.GenericSerif, 18, FontStyle.Regular)
e.Graphics.DrawString("Page #" & PageCount, f, Brushes.Black, 10, 10)

PageCount += 1
If PageCount <= 3 Then
e.HasMorePages = True
End If

End Sub
 
You would want to do a test in the PrintPage event. Something like if

If PageCount = One_Of_The_Pages_I_Want Then
Draw Graphics
Else
Don't Draw graphics
End If
 
I tried it, but it still prints all of the pages. Except now the pages that aren't in range are blank, since I didn't draw anything when the PrintPage event was called for them.
 
Look into e.Cancel. I'm not sure if it's going to cancel only the current event, which would be great, or if it is going to cancel the entire print job.
 
Code:
    PageCount += 1
    If PageCount <= 3 Then
        e.HasMorePages = True
    End If
Not at all familiar with this printer object. However, logic would suggest that if you set hasmorepages to true, you're telling the printer that there are more pages to print. I don't see where you set it to false anywhere. Could that be the problem? Maybe
Code:
    PageCount += 1
    e.HasMorePages = (PageCount <= 3)
would fix the problem.
 
If they wanted to skip page 1 and start on page 2, HasMorePages would never get to page 2.
 
To BobRodes:

The HasMorePages property of e defaults to false. When it is set to false the print job is finished. So setting that value to false on pages that aren't in the range of pages to print would cause the pages afterwards to stop printing.

For example, if I wanted to print pages 2-3, when the PrintPage method would be encountered for the first page, it would set HasMorePages to false, thus stopping pages 2 and 3 from printing as well.

But thaks a lot for helping. I'm going to modify my code to resemble your suggestion anyway, since it's easier to read. Do you have any other ideas?
 
BigSassy, I have done a bit of experimenting:

Code:
  Private ThisPage As Integer
  Private LastPage As Integer
  Private WithEvents PrintDocument As PrintDocument

  Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

    With PrintDialog1
      .AllowPrintToFile = True
      .AllowSelection = True
      .AllowSomePages = True
      .PrinterSettings = New PrinterSettings
      With .PrinterSettings
        .PrintRange = PrintRange.SomePages
        .FromPage = 1
        .ToPage = 100
        .MinimumPage = 1
        .MaximumPage = 100
      End With
      If .ShowDialog = DialogResult.OK Then
        If .PrinterSettings.PrintRange = PrintRange.SomePages Then
          DoPrint(.PrinterSettings.FromPage, .PrinterSettings.ToPage)
        Else
          DoPrint()
        End If
      Else
        Exit Sub
      End If
    End With

  End Sub

  Private Sub DoPrint()
    'not implemented
  End Sub
  Private Sub DoPrint(ByVal StartPage As Integer, ByVal EndPage As Integer)

    ThisPage = StartPage
    LastPage = EndPage
    PrintDocument = New PrintDocument
    Try
      PrintDocument.Print()
    Catch ex As Exception
      MessageBox.Show(ex.Message)
    End Try

  End Sub

  Private Sub PrintDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument.PrintPage

    Dim f As New Font(FontFamily.GenericSerif, 18, FontStyle.Regular)
    e.Graphics.DrawString("Page #" & ThisPage, f, Brushes.Black, 10, 10)

    ThisPage += 1
    e.HasMorePages = ThisPage <= LastPage

  End Sub

requires Imports System.Drawing.Printing


I've tested this by changing values in the print dialog box (which open with From 1 To 100)

1 -> 3
2 -> 3
56 -> 60

In each case it only prints the required pages.

Hope this helps.
 
Ok, I get it. Thanks BigSassy. E&F, is your "PrintRange.SomePages" defined in System.Drawing.Printing or elsewhere?

Bob
 
I haven't got VS running at the moment so I can't find out, but ...

type

PrintDialog1.PrinterSettings.PrintRange = PrintRange.

and Intellisense will tell you what options are available.

In fact, I think Intellisense will kick in when you type =

Hope this helps.
 
Ah, I see. Thanks earthandfire. I know what I need to do now. Thank you so much everyone. This has been driving me nuts for too long :)
 
Well, in the real application I had a report class that handled laying out and printing the information on the Graphics object for the PrintDocument's PrintPage event. Long story short, I defined the first and last row of the data for each page. Then I just made a method that got the starting row of the ToPage and the end row of the FromPage.

The code's a little too complicated for me to go into more detail and keep the post short. If I had to re-code the class I'd do things much differently, but when you get behind on a project, sometimes you gotta do what you gotta do :)
 
I never get behind on a project. The project usualy gets in front of me.

Christiaan Baes
Belgium

I just like this --> [Wiggle] [Wiggle]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top