Drucken bestimmte Seiten

  • VB.NET

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von ChristianL.

    Drucken bestimmte Seiten

    Hallo zusammen,

    ich komme leider wieder einmal mit einem Druckproblem, das ich aber noch nirgends gelöst gefunden habe.
    Vorweg: Das mehrseitige Drucken funktioniert.
    Zuerst erfolgt eine Anzeige in einem abgeleiteten PrintPreviewDialog (Class MyPrintPreviewDialog)
    Allerdings funktioniert die Auswahl bestimmter Seiten im PrintDialog nicht ( AllowSomePages = True, FromPage und ToPage sind gesetzt ?!)
    Und die Anzeige von CurrentPage (AllowCurrentPage = True) gibt es im PrintDialog gar nicht ?!
    Egal, welche Einstellung der User im PrintDialog trifft, es werden immer alle Seiten gedruckt.
    Bitte Hilfe, Danke im Voraus.

    VB.NET-Quellcode

    1. Public Class MyPrintPreviewDialog
    2. Inherits PrintPreviewDialog
    3. Private btn As ToolStripButton
    4. Private UpDown As NumericUpDown
    5. Public Sub New()
    6. 'Toolstrip finden
    7. Dim ts As ToolStrip = CType(Controls.Find("toolstrip1", True)(0), ToolStrip)
    8. 'Drucken Button finden
    9. btn = CType(ts.Items.Item(0), ToolStripButton)
    10. 'Neuen Drucken Button mit Handler erstellen
    11. Dim b As New ToolStripButton("", btn.Image, AddressOf PrintClick) With {.Name = "DruckButton"}
    12. 'Originalen Button entfernen
    13. ts.Items.RemoveAt(0)
    14. 'Neuen Button hinzufügen
    15. ts.Items.Insert(0, b)
    16. 'NumericUpDown suchen und auf UpDown setzen
    17. For Each c As Object In ts.Items
    18. If TypeOf c Is ToolStripControlHost Then
    19. 'Dim tsch As ToolStripControlHost = CType(c, ToolStripControlHost)
    20. ' Dim co As Control = tsch.Control
    21. UpDown = CType(CType(c, ToolStripControlHost).Control, NumericUpDown)
    22. End If
    23. Next
    24. End Sub
    25. Private Sub PrintClick(ByVal sender As Object, ByVal e As System.EventArgs)
    26. Dim pd As New PrintDialog With {
    27. .PrinterSettings = Document.PrinterSettings,
    28. .AllowCurrentPage = True,
    29. .AllowSelection = False,
    30. .AllowSomePages = True,
    31. .AllowPrintToFile = False,
    32. .Document = Document
    33. }
    34. If pd.ShowDialog = DialogResult.OK Then
    35. ' Dem printDocument die neuen Einstellungen zuweisen und Drucken
    36. ' starten
    37. ' Document.PrinterSettings = pd.PrinterSettings
    38. Document = pd.Document
    39. ' btn.PerformClick()
    40. Select Case Document.PrinterSettings.PrintRange
    41. Case PrintRange.AllPages
    42. Console.WriteLine("alles drucken")
    43. Case PrintRange.CurrentPage
    44. Console.WriteLine("aktuelle Seite drucken")
    45. Document.PrinterSettings.FromPage = CInt(UpDown.Value)
    46. Document.PrinterSettings.ToPage = CInt(UpDown.Value)
    47. 'TODO somePages funktioniert nicht
    48. Case PrintRange.SomePages
    49. Console.WriteLine("ein paar Seiten drucken")
    50. Document.PrinterSettings.FromPage = 2 'nur zu Testzwecken
    51. Document.PrinterSettings.ToPage = 3
    52. End Select
    53. 'Console.WriteLine("fromPage=" & Document.PrinterSettings.FromPage.ToString)
    54. Document.Print()
    55. Close() ' Den PrintPreviewDialog schließen
    56. End If
    57. End Sub
    58. Private Sub MyPrintPreviewDialog_Load(sender As Object, e As EventArgs) Handles Me.Load
    59. Location = My.Settings.DruckVorschauFormPosition
    60. If Document.DefaultPageSettings.Landscape Then
    61. Size = New Size(900, 600)
    62. Else
    63. Size = New Size(600, 900)
    64. End If
    65. End Sub
    66. Private Sub MyPrintPreviewDialog_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
    67. My.Settings.DruckVorschauFormPosition = Location
    68. My.Settings.Save()
    69. End Sub
    70. Private Sub MyPrintPreviewDialog_MouseWheel(sender As Object, e As MouseEventArgs) Handles Me.MouseWheel
    71. Dim v As Decimal = e.Delta / 120
    72. 'If UpDown.Value + v < 0 Then
    73. ' UpDown.Value = 0
    74. ' Exit Sub
    75. 'End If
    76. 'If UpDown.Value + v > 100 Then
    77. ' UpDown.Value = 100
    78. ' Exit Sub
    79. 'End If
    80. UpDown.Value -= v ' minus, weil "hinunterblättern"
    81. End Sub
    82. End Class

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ChristianL“ ()

    Willkommen im Forum. :thumbup:

    ChristianL schrieb:

    es werden immer alle Seiten gedruckt.
    Klar.
    Woher soll Bill Gates wissen, was Du auf die 5. Seite drucken willst?
    Das, was gedruckt werden soll, musst Du im PrintPage-Eventhandler selbst organisieren.
    Wenn Du mit PreView druckst, musst Du Dir im "Trockendurchlauf" merken, womit Seite 5 bedruckt werden soll.
    Im zweiten Druck-Lauf druckst Du dann genau das, was da hin muss.
    Oder
    Du hast eine harte Seitenstruktur, die Du in einer For- oder Do-Schleife abarbeitest, da gehst Du einfach nur mit dem richtigen Index rein und feddich. ;)
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @ErfinderDesRades: ich habe leider beim ersten Versuch [ v b n e t] [ / v b n e t ] statt [ c o d e = v b n e t ] [ / c o d e ] verwendet ... Bug oder Feature? ;)

    @RodFromGermany: Hallo Rod, die Druckaufbereitung funktioniert, die Seiten werden im "Trockendurchlauf" gerendert, dann im PrintPreview (richtig) angezeigt, und dann auch richtig gedruckt.

    Ich möchte jetzt dem User die Möglichkeit geben, von einem printDokument, das zum Beispiel 5 Seiten hat, zum Beispiel nur die Seiten 2-3 auszudrucken. Oder auch nur die angezeigte Seite auszudrucken (CurrentPage ??)
    Artikel:docs.microsoft.com/de-de/dotne…a-printdialog-at-run-time

    Was ich sonst darüber im msdn gefunden habe, sollte das über die Eigenschaften printDocument.PrinterSettings.FromPage und .ToPage definiert werden. Diese Einstellungen werden vom User im PrintDialog (Achtung: Nicht PrintPreviewDialog!) eingestellt. Allerdings dürfte die Rückübergabe dieser Einstellungen bei mir nicht funktionieren. (Rückgabe mit: printDocument = Printdialog.Document ??) Habe ich da grundsätzlich etwas falsch verstanden?

    Der Vollständigkeit halber hier noch der Code, wie die Klassse MyPrintPreviewDialog verwendet wird:
    (Anm.: dies ist eine ausgekoppelte Testsolution, und nicht das eigentliche Projekt)
    (Anm.: Zum Ausführen benötigt: Form1 mit einem Button.Name="DruckButton", außerdem Verweis System.Drawing.Printing)

    VB.NET-Quellcode

    1. Imports System.ComponentModel
    2. Public Class Form1
    3. Friend WithEvents P_doc As PrintDocument
    4. Private Seitenzahlen As Integer = 5
    5. Private Seitenzahl As Integer = 1
    6. Private Sub DruckButton_Click(sender As Object, e As EventArgs) Handles DruckButton.Click
    7. Dim PreviewDL As New MyPrintPreviewDialog
    8. Seitenzahlen = 5
    9. Seitenzahl = 0
    10. P_doc = New PrintDocument With {
    11. .DocumentName = "der name des Dokuments"}
    12. P_doc.DefaultPageSettings.Landscape = False
    13. PreviewDL.Document = P_doc
    14. PreviewDL.ShowDialog()
    15. P_doc = Nothing
    16. End Sub
    17. Private Sub PerformPrint(sender As Object, e As PrintPageEventArgs) Handles P_doc.PrintPage
    18. Dim fo As New Font("Arial", 50, FontStyle.Regular)
    19. Seitenzahl += 1
    20. e.Graphics.DrawString(Seitenzahl.ToString, fo, Brushes.Black, 50, 50)
    21. If Seitenzahl < Seitenzahlen Then
    22. e.HasMorePages = True
    23. Else
    24. e.HasMorePages = False
    25. Seitenzahl = 0
    26. End If
    27. End Sub
    28. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    29. Location = My.Settings.FormPosition
    30. End Sub
    31. Private Sub Form1_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
    32. My.Settings.FormPosition = Location
    33. My.Settings.Save()
    34. End Sub
    35. End Class

    Dieser Beitrag wurde bereits 12 mal editiert, zuletzt von „ChristianL“ ()

    ChristianL schrieb:

    P_doc = Nothing
    Was soll das?
    Try this:

    VB.NET-Quellcode

    1. Private Sub PrintDocument1_BeginPrint(sender As Object, e As Printing.PrintEventArgs) Handles P_doc.BeginPrint
    2. Seitenzahl = 2
    3. Seitenzahlen = 4
    4. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    VB.NET-Quellcode

    1. P_Doc = Nothing

    gibt einfach bei Beendigung den Speicher frei

    Dies betrifft aber nicht mein Problem...
    Ich möchte das fertige Printdocument (in dem im PrintPreview ALLE Seiten angezeigt werden) einschränken, bitte meine vorherigen Posts lesen!, siehe FromPage, ToPage , AllowSomePages

    Das Problem müsste in der Class MyPrintPreviewDialog -> Sub PrintClick liegen...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ChristianL“ ()

    @ChristianL Das PrintDSocument wird noch gebraucht.
    Try this:

    VB.NET-Quellcode

    1. Private Sub PrintDocument1_BeginPrint(sender As Object, e As Printing.PrintEventArgs) Handles P_doc.BeginPrint
    2. Seitenzahl = 2
    3. Seitenzahlen = 4
    4. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    ChristianL schrieb:

    Aber nicht die Einschränkung mit FromPage und ToPage

    RodFromGermany schrieb:

    Try this:

    VB.NET-Quellcode

    1. Private Sub PrintDocument1_BeginPrint(sender As Object, e As Printing.PrintEventArgs) Handles P_doc.BeginPrint
    2. Seitenzahl = 2
    3. Seitenzahlen = 4
    4. End Sub
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Nach einigem Herumprobieren und Lesen habe ich jetzt folgendes gefunden:
    social.msdn.microsoft.com/Foru…tdocument?forum=vbgeneral

    "You can not draw until you reach the start page or clear the drawing when you reach the start page."

    Bedeutet also, dass mein Ansatz falsch war.
    Wenn man nur einige Seiten drucken möchte, muss (und kann nur) die PrintPage -Sub
    geändert werden.
    Für mein Beispiel habe ich es geschafft, für mein eigentliches Projekt wird es aber noch einige Arbeit, die (verschiedenen) PrintPage Ereignisse entsprechend zu bearbeiten.
    Bin von der Microsoft-Dokumentation enttäuscht, die mir und anderen gewisse falsche Hoffnungen erweckt hat.
    Danke Rod fürs Helfen!
    Thema erledigt, wen's interessiert, hier die Lösung (etwas unbefriedigend):

    VB.NET-Quellcode

    1. Private Sub PerformPrint(sender As Object, e As PrintPageEventArgs) Handles P_doc.PrintPage
    2. Dim fo As New Font("Arial", 50, FontStyle.Regular)
    3. Seitenzahl += 1
    4. If e.PageSettings.PrinterSettings.PrintRange = PrintRange.SomePages Then
    5. Do While Seitenzahl < e.PageSettings.PrinterSettings.FromPage
    6. Seitenzahl += 1 'hier fehlt das Überspringen der nicht zu druckenden Daten
    7. Loop
    8. End If
    9. e.Graphics.DrawString(Seitenzahl.ToString, fo, Brushes.Black, 50, 50)
    10. If e.PageSettings.PrinterSettings.PrintRange = PrintRange.SomePages AndAlso Seitenzahl >= e.PageSettings.PrinterSettings.ToPage Then
    11. e.HasMorePages = False
    12. Seitenzahl = 0
    13. Exit Sub
    14. End If
    15. If Seitenzahl < Seitenzahlen Then
    16. e.HasMorePages = True
    17. Else
    18. e.HasMorePages = False
    19. Seitenzahl = 0
    20. End If
    21. End Sub


    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „ChristianL“ ()