如何设置PrintDocument的边距?

时间:2017-09-08 14:48:05

标签: .net vb.net

我正在努力让用户设置报告的边距。现在我有硬编码,但我更喜欢在运行时设置它们,以便它们可以更改。我试过这个:

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

打印1/4“边距,远远超出打印机的硬边距。没有打印。根据Margins,参数是数百英寸。如果我将代码更改为:

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

我的输出效果很好: Good output

但是当我将代码更改为:

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

这就是我得到的,这没有任何意义。它看起来像是超过1英寸: Bad output

而且我不是唯一一个有边距问题的人,有no response here我甚至发布到微软,no response.

由于报告编写者可以生成大多数文档,我认为没有多少人使用PrintDocument对象。所以我在向微软报告一个错误之前,已经看到了这里有什么人要说的,这需要相当长的时间才能得到回应。

编辑:我做了一个更简单的版本并得到了相似但仍然很奇怪的结果。我不得不在类,类定义,属性等中留下很多代码。调用者需要的。我刚刚删除了(差不多)事件中的所有代码。

以下是事件代码:

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

产生(看起来不到1/8英寸): Less

改变:

Me.DefaultPageSettings.Margins = New Margins(20, 20, 23, 23)

产生(看起来超过1/4英寸): enter image description here

EDIT2:我尝试了TnTinMn的技术,我很难理解TranslateTransform method.从我的测试来看,它几乎听起来像是“添加”到你拥有​​的任何边缘。更糟糕的是,如果我使用0,我获得的边距比我设置的更大, OriginAtMargins 在这一点上没有任何区别。我想要做的是在打印机之间创建一致的保证金。

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

哪个产生: enter image description here

我可以将TranslateTransform调用更改为:

e.Graphics.TranslateTransform(-e.MarginBounds.X / 100.0F, -e.MarginBounds.Y / 100.0F)

哪个产生了这个,更好,但我已经有一个黑客工作。我想弄清楚如何做到这一点。

enter image description here

如何正确使用PrintDocument似乎是一个很大的谜。

当我使用PrintDocument时,TnTinMn正在使用PrintController。我尝试将他提议的改变纳入其中并且根本不起作用。知道如何让这两个对象一起工作吗?

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

我改变了另一堂课。

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

相同的结果。

编辑决赛: TnTinMn的解决方案非常有效。我想我在这里复制代码,我的测试DLL和生产DLL之间发生了错误。在任何情况下,我都会重新考虑所有事情,虽然更加谨慎一点,但它确实有效。以下是在测试中使用的代码(以及在生产中使用的相同技术)

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

我设置1/4“边距,我得到1/4”边距!这是我的第7张截图,幸运#7。

enter image description here

1 个答案:

答案 0 :(得分:2)

PrintPage处理程序中,您有语句e.Graphics.PageUnit = GraphicsUnit.Inch,从而导致问题。收到的e.Graphics.PageUnit设置为Display,图形会应用一个反映您OriginAtMargins = True设置的坐标转换。转型' OffsetXOffsetY值是使用Display PageUnit设置(1/100英寸)计算的。当您将PageUnit更改为Inch时,这些偏移现在被解释为英寸,而您在图形上绘制的任何内容都会被绘制出界限。这就是你得到一个空页面的原因。

您应该能够消除OriginAtMargins = True语句并修改PrintPage处理程序代码,如下所示:

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)

编辑:我更正了TranslateTransform参数,以说明我最初忽略的打印机硬边距值。这是基于StandardPrintController.OnStartPage方法在PrintDocument.OriginAtMargins属性为真时执行的转换。