I am having a terrible time trying to allow the user to set the margins for a report. Right now I have it hard coded but I would prefer to set them at run time so they can be changed. I tried this:
Private Sub rotHCReport_BeginPrint(ByVal sender As Object, _
      ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.BeginPrint
    Me.OriginAtMargins = True
    Me.DefaultPageSettings.Margins = New Margins(25, 25, 25, 25)
End Sub
To print a 1/4" margin which is well beyond the printer's hard margins. Nothing prints. According to Margins the arguments are in hundreds of an inch. If I change the code to:
Private Sub rotHCReport_BeginPrint(ByVal sender As Object, _
      ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.BeginPrint
    Me.OriginAtMargins = True
    Me.DefaultPageSettings.Margins = New Margins(20, 20, 23, 23)
End Sub
I do get good output:

But when I change the code to:
Private Sub rotHCReport_BeginPrint(ByVal sender As Object, _
      ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.BeginPrint
    Me.OriginAtMargins = True
    Me.DefaultPageSettings.Margins = New Margins(21, 20, 23, 23)
End Sub
This is what I get, which makes no sense.  It looks like it shifts over 1 inch:

And I am not the only one having problems with margins, there is no response here and I even posted to microsoft, with no response.
Since report writers can produce the majority of documents I will presume not many people use the PrintDocument object. So I am seeing what anyone here has to say before I report a bug to Microsoft, which will take a considerable time for a response to come from then.
EDIT: I made a simpler version and got similar but still strange results. I had to leave a lot of the code in the class, class definitions, properties, ect. that the caller requires. I just removed (almost) all the code from the events.
Here is the event code:
Private Sub rotHCReport_BeginPrint(ByVal sender As Object, _
      ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.BeginPrint
    Me.OriginAtMargins = True
    Me.DefaultPageSettings.Margins = New Margins(19, 20, 23, 23)
    mintLevel = 0
    'Reset the loop trackers (used when we need to break out to print a page but remember our place) and others.
    mintRowLoopStart = 0
    mintTableLoopStart = 0
    'Flags
    ResetHeaderFooterFlags()
    'Page counters
    mintCurrentPage = 0
    mintTotalPages = 0
End Sub
Private Sub rotHCReport_QueryPageSettings(ByVal sender As Object, _
     ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) Handles Me.QueryPageSettings
    e.PageSettings.Landscape = mePageOrientation = Orientation.Landscape
    mintCurrentPage += 1
End Sub
Private Sub rotHCReport_PrintPage(ByVal sender As Object, _
    ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles Me.PrintPage
    Dim DR As DataRow
    Dim PrintFont As Font
    e.Graphics.PageUnit = GraphicsUnit.Inch
    PrintFont = New Font("Arial", 8, FontStyle.Regular)
    For intRow = 0 To 10
        DR = mDS.Tables(0).Rows(intRow)
        For intColumn = 0 To 5
            e.Graphics.DrawString(DR(intColumn).ToString, PrintFont, New SolidBrush(Color.Black), intColumn + 1, CSng(intRow + 1))
        Next
    Next
End Sub
Private Sub rotHCReport_EndPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.EndPrint
    mbSetUpRequired = True
End Sub
Which produces (looks less than 1/8 of an inch):

And changing:
Me.DefaultPageSettings.Margins = New Margins(20, 20, 23, 23)
Produces (looks more than 1/4 inch):

EDIT2: I tried TnTinMn's technique and I had a difficult time understanding the TranslateTransform method. From my testing it almost sounds like it "adds" to whatever margin you have. Worse, if I use 0 I get a larger margin than what I have set, OriginAtMargins makes no difference at this point. What I am trying to do is create a consistent margin across printers.
Private Sub rotHCReport_BeginPrint(ByVal sender As Object, _
      ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.BeginPrint
    'Me.OriginAtMargins = True
    Me.DefaultPageSettings.Margins = New Margins(25, 25, 25, 25)
    'Subreport level
    mintLevel = 0
    'Reset the loop trackers (used when we need to break out to print a page but remember our place) and others.
    mintRowLoopStart = 0
    mintTableLoopStart = 0
    'Flags
    ResetHeaderFooterFlags()
    'Page counters
    mintCurrentPage = 0
    mintTotalPages = 0
End Sub
Private Sub rotHCReport_QueryPageSettings(ByVal sender As Object, _
     ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) Handles Me.QueryPageSettings
    e.PageSettings.Landscape = mePageOrientation = Orientation.Landscape
    mintCurrentPage += 1
End Sub
Private Sub rotHCReport_PrintPage(ByVal sender As Object, _
    ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles Me.PrintPage
    Dim DR As DataRow
    Dim PrintFont As Font
    e.Graphics.PageUnit = GraphicsUnit.Inch
    e.Graphics.ResetTransform()
    e.Graphics.TranslateTransform(e.MarginBounds.X / 100.0F, e.MarginBounds.Y / 100.0F)
    PrintFont = New Font("Arial", 8, FontStyle.Regular)
    For intRow = 0 To 10
        DR = mDS.Tables(0).Rows(intRow)
        For intColumn = 0 To 5
            e.Graphics.DrawString(DR(intColumn).ToString, PrintFont, New SolidBrush(Color.Black), CSng(intColumn + 1), CSng(intRow + 1))
        Next
    Next
End Sub
Private Sub rotHCReport_EndPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.EndPrint
    mbSetUpRequired = True
End Sub
Which produces:

I can change the TranslateTransform call to this:
e.Graphics.TranslateTransform(-e.MarginBounds.X / 100.0F, -e.MarginBounds.Y / 100.0F)
Which produces this, better, but I already have a hack job working. I am trying to figure out how to do this right.

It seems a great mystery on how to use the PrintDocument properly.
TnTinMn is using the PrintController while I am using the PrintDocument. I tried incorporating his proposed change and it did not work at all. Any idea how to get these two object to work together?
Public Class NewController
    Inherits PrintController
    Public Overrides Function OnStartPage(ByVal document As System.Drawing.Printing.PrintDocument, ByVal e As System.Drawing.Printing.PrintPageEventArgs) As System.Drawing.Graphics
        Dim g As System.Drawing.Graphics
        g = MyBase.OnStartPage(document, e)
        g.PageUnit = GraphicsUnit.Inch
        g.ResetTransform()
        g.TranslateTransform((e.MarginBounds.X - e.PageSettings.HardMarginX) / 100.0F, (e.MarginBounds.Y - e.PageSettings.HardMarginY) / 100.0F)
        'This does not work either
        'e.Graphics.PageUnit = GraphicsUnit.Inch
        'e.Graphics.ResetTransform()
        'e.Graphics.TranslateTransform((e.MarginBounds.X - e.PageSettings.HardMarginX) / 100.0F, (e.MarginBounds.Y - e.PageSettings.HardMarginY) / 100.0F)
        'Return e.Graphics
        Return g
    End Function
End Class
And I changed the other class.
Private mPC As NewController
Public Sub New()
    MyBase.New()
    mPC = New NewController
    Me.PrintController = mPC
End Sub
Private Sub rotHCReport_BeginPrint(ByVal sender As Object, _
      ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.BeginPrint
    Me.DefaultPageSettings.Margins = New Margins(25, 25, 25, 25)
    'Subreport level
    mintLevel = 0
    'Reset the loop trackers (used when we need to break out to print a page but remember our place) and others.
    mintRowLoopStart = 0
    mintTableLoopStart = 0
    'Flags
    ResetHeaderFooterFlags()
    'Page counters
    mintCurrentPage = 0
    mintTotalPages = 0
End Sub
'Raised before each and every page
Private Sub rotHCReport_QueryPageSettings(ByVal sender As Object, _
     ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) Handles Me.QueryPageSettings
    e.PageSettings.Landscape = mePageOrientation = Orientation.Landscape
    mintCurrentPage += 1
End Sub
Private Sub rotHCReport_PrintPage(ByVal sender As Object, _
    ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles Me.PrintPage
    Dim DR As DataRow
    Dim PrintFont As Font
    e.Graphics.PageUnit = GraphicsUnit.Inch
    PrintFont = New Font("Arial", 8, FontStyle.Regular)
    For intRow = 0 To 10
        DR = mDS.Tables(0).Rows(intRow)
        For intColumn = 0 To 5
            e.Graphics.DrawString(DR(intColumn).ToString, PrintFont, New SolidBrush(Color.Black), CSng(intColumn + 1), CSng(intRow + 1))
            'millimetersd
            'e.Graphics.DrawString(DR(intColumn).ToString, PrintFont, New SolidBrush(Color.Black), CSng((intColumn + 1) * 25.4), CSng((intRow + 1) * 25.4))
        Next
    Next
End Sub
Private Sub rotHCReport_EndPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.EndPrint
    mbSetUpRequired = True
End Sub
Same results.
EDIT FINAL: TnTinMn's solution worked perfectly. I think I made an error somewhere copying the code between here, my test dll and production dll. In any event, I went over everything again, albeit a little more carefully and it worked. Here is the code that worked in test (and the same technique worked in production)
Private Sub rotHCReport_BeginPrint(ByVal sender As Object, _
      ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.BeginPrint
    'Me.OriginAtMargins = True 'Don't need this anymore
    Me.DefaultPageSettings.Margins = New Margins(25, 25, 25, 25) 'These are the margins actually used
    'Subreport level
    mintLevel = 0
    'Reset the loop trackers (used when we need to break out to print a page but remember our place) and others.
    mintRowLoopStart = 0
    mintTableLoopStart = 0
    'Flags
    ResetHeaderFooterFlags()
    'Page counters
    mintCurrentPage = 0
    mintTotalPages = 0
End Sub
'Raised before each and every page
Private Sub rotHCReport_QueryPageSettings(ByVal sender As Object, _
     ByVal e As System.Drawing.Printing.QueryPageSettingsEventArgs) Handles Me.QueryPageSettings
    e.PageSettings.Landscape = mePageOrientation = Orientation.Landscape
    mintCurrentPage += 1
End Sub
Private Sub rotHCReport_PrintPage(ByVal sender As Object, _
    ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles Me.PrintPage
    Dim DR As DataRow
    Dim PrintFont As Font
    e.Graphics.PageUnit = GraphicsUnit.Inch
    e.Graphics.ResetTransform()
    e.Graphics.TranslateTransform((e.MarginBounds.X - e.PageSettings.HardMarginX) / 100.0F, (e.MarginBounds.Y - e.PageSettings.HardMarginY) / 100.0F)
    PrintFont = New Font("Arial", 8, FontStyle.Regular)
    For intRow = 0 To 10
        DR = mDS.Tables(0).Rows(intRow)
        For intColumn = 0 To 5
            e.Graphics.DrawString(DR(intColumn).ToString, PrintFont, New SolidBrush(Color.Black), CSng(0.25 + intColumn), CSng(0.25 + intRow))
        Next
    Next
End Sub
Private Sub rotHCReport_EndPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles Me.EndPrint
    mbSetUpRequired = True
End Sub
I set 1/4" margins and I got 1/4" margins! Here's my 7th screenshot, lucky #7.

In your PrintPage handler, you have the statement e.Graphics.PageUnit = GraphicsUnit.Inch and are thus causing the problem.  The received e.Graphics.PageUnit is set to Display and the Graphics has a coordinate  transform applied to it that reflects your OriginAtMargins = True setting.  The transforms' OffsetX and OffsetY values were computed using the Display PageUnit setting (in 1/100 inch).  When you change the PageUnit to Inch those offsets are now interpreted as Inches and whatever you are drawing on the Graphics is drawn out of bounds.  This is why you get an empty page.
You should be able to eliminate the OriginAtMargins = True statement and modify the PrintPage handler code like this:
e.Graphics.PageUnit = GraphicsUnit.Inch
e.Graphics.ResetTransform() ' clear any previous transforms
e.Graphics.TranslateTransform((e.MarginBounds.X - e.PageSettings.HardMarginX) / 100.0F, (e.MarginBounds.X - e.PageSettings.HardMarginY) / 100.0F)
Edit:  I corrected the TranslateTransform arguments to account for the printer's hard margin values that I originally neglected.  This is based on the transform performed by the StandardPrintController.OnStartPage method when then PrintDocument.OriginAtMargins property is true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With