Drucken von mehreren Formen

  • VB.NET

Es gibt 20 Antworten in diesem Thema. Der letzte Beitrag () ist von RodFromGermany.

    Drucken von mehreren Formen

    Moin moin,

    ich versuche mich nun seit fast 2 Wochen mit Visual Basic 2010 Express.

    Soweit komme ich auch klar :D
    Ich habe nun das Problem das ich die Formen nicht so drucken kann wie ich will ^^

    Zu meinen Beispiel:

    Ich habe 3 Windows- Formen, wo ich Eingaben mache
    - Form1/ Produktauswahl
    - Form2 / Kundenauswahl
    - Form3 / Informationsseite

    Auf Seite 1 (Form1) ist unten rechts ein Button eingebaut um auf die nächste Seite (Form2) zu gelangen.
    Dabei setze ich Form1 auf Hide.
    Von Seite 2 auf Seite 3 das selbe natürlich - nur das ich auf Seite 3 unten rechts nun ein Button habe der die 3 Seiten drucken soll.

    Ich bekomme es aber nur hin die letzte Seite - also wo auch der Druck-Button ist - gedruckt wird.

    Ist das irgendwie - am besten unkompliziert - möglich? Ich habe mir schon so viele Seiten und Videos angeschaut. Da wird aber immer nur die Möglichkeit aufgezeigt, wie die derzeitige Seite gedruckt wird.

    Für jeden Tipp/Vorschlag/Rat wäre ich dankbar.

    Mit freundlichen Gruß aus dem Norden :)
    @Akiju87 Willkommen im Forum. :thumbup:
    Denk mal wesentlich einfacher: Nimm nur eine Form, nimm ein TabControl, das geht auch ohne Reiter, oder nimm ein DataGrigView und eine DataTable.
    Zum Drucken selbst gugst Du hier.
    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!
    Vielen Dank für die Antworten. Das mit den Tabs ist echt besser/einfacher. Nur hab ich da auch irgendwie das Druck- Problem.
    Ich hätte gerne die Seite als ganzes angezeigt -also mit Checkboxen, Labels usw.

    So wie ich das nun verstanden habe müsste ich den Druckbefehl sagen wo was stehen soll - oder mache ich das völlig falsch? :S


    Mit dem ReprtViewer kann ich erstmal nichts anfangen. Ich habe nur die Express- Version.
    Mit gefährlichen halbwissen will ich da nicht so viel Geld für ausgeben :D

    Akiju87 schrieb:

    wo was stehen soll
    Das ist korrekt.
    Natürlich kannst Du auch Deine Form als solche (äquivalent zu PrintScreen) drucken:

    VB.NET-Quellcode

    1. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. Dim ctrl As Control = Me.TabControl1 ' das zu druckende Control
    3. Dim bmp As New Bitmap(ctrl.Width, ctrl.Height)
    4. ctrl.DrawToBitmap(bmp, New Rectangle(0, 0, ctrl.Width, ctrl.Height))
    5. If Me.PictureBox1.Image IsNot Nothing Then
    6. Me.PictureBox1.Image.Dispose()
    7. End If
    8. Me.PictureBox1.Image = bmp ' hier halt verwenden
    9. 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!
    @Akiju87 Dazu musst Du zunächst verstehen, wie der mehrseitige Druck funktioniert.
    Für jede einzelne Seite wird das Ereignis PrintPage aufgerufen, und das hanze (über alle Seiten) je 2 Mal, einmal für das Preview, einmal für den Druckauftrag selbst.
    Du musst selbst zählen, welche Seite gerade gedruckt wird und dann entscheiden, was auf die aktuelle Seite kommt.
    Bei der letzten Seite wird .HasMorePages auf false gesetzt:
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim lfdNb As Integer
    3. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    4. Using dlg As New PrintPreviewDialog
    5. dlg.Document = Me.PrintDocument1
    6. dlg.ShowDialog()
    7. End Using
    8. End Sub
    9. Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    10. lfdNb += 1
    11. Dim txt = "Dies ist Seite " & lfdNb
    12. e.Graphics.DrawString(txt, New Font("Arial", 30), Brushes.Black, New Point(10, 10))
    13. If lfdNb = 4 Then
    14. e.Graphics.DrawString("Das war es", New Font("Arial", 30), Brushes.Black, New Point(10, 50))
    15. End If
    16. e.HasMorePages = lfdNb < 4
    17. End Sub
    18. Private Sub PrintDocument1_BeginPrint(sender As Object, e As Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
    19. lfdNb = 0
    20. End Sub
    21. End Class
    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!
    Das ist ja das was ich nicht will ^^

    Ich hätte gedacht das es einfacher wäre ein Abbild der jeweiligen Form bzw. TabPage zu erstellen und diese dann zu drucken.
    Das bekomme ich ja soweit hin - aber leider nur immer die aktuelle Form bzw. TabPage.

    Ich will halt TabPage1 (auf Seite 1) und TabPage2 (auf Seite 2) drucken.. Und das bringt mich um den Verstand :D

    Vielen Dank für die Antworten.
    Die bringen immer ein wenig mehr Licht ins dunkele :saint:

    Akiju87 schrieb:

    was ich nicht will

    Akiju87 schrieb:

    Ich will halt TabPage1 (auf Seite 1) und TabPage2 (auf Seite 2) drucken
    Ja was denn nun?
    Ob Du nun einen String oder ein Bild druckst, ist doch egal.
    Du musst nur die Bilder generieren und geeignet zwischenspeichern zum Drucken.
    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!
    Sorry für den Nervenraub :/

    Ich will nicht sagen müssen was ich wo gedruckt haben will..

    Ich hole nochmal ein wenig aus:

    Ich habe ein Formular erstellt. Auf TabPage1 sind Textboxen, Checkboxen und Labels vorhanden. Z.B. Name, Vorname, usw..
    Auf TabPage2 sind Angeben zu einer Produktauswahl aufgelistet. Ebenfalls mit Labels und Checkboxen.

    Nun hätte ich gerne das ich über eine Menüleiste - die ich bereits habe ^^ - den Druckbefehl ausführen kann.
    Aber eben für beide Seiten auf einmal. Ich bekomme es nur hin das er mir die aktuelle Seite (TabPage) als Vorschau zeigt bzw. druckt.

    Ich merk schon ich hätte es lieber sein lassen sollen.. :D
    @Akiju87 So was (Pseudocode):

    VB.NET-Quellcode

    1. Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    2. lfdNb += 1
    3. e.Graphics.DrawString(txt, New Font("Arial", 30), Brushes.Black, New Point(10, 10))
    4. If lfdNb = 1 Then
    5. e.Graphics.DrawImage(TAB_PAGE_1)
    6. Else If lfdNb = 2 Then
    7. e.Graphics.DrawImage(TAB_PAGE_2)
    8. Else If lfdNb = 3 Then
    9. e.Graphics.DrawImage(TAB_PAGE_3)
    10. End If
    11. e.HasMorePages = lfdNb < 3
    12. End Sub
    13. Private Sub PrintDocument1_BeginPrint(sender As Object, e As Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
    14. lfdNb = 0
    15. 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!
    Ich habe da nochmal eine Vorlage genommen (aus einem andern Forum):

    Quellcode

    1. Private Function GetImage1() As Bitmap
    2. Dim bm As New Bitmap(Me.TabControl1.TabPages("PAGE1").ClientSize.Width, Me.TabControl1.TabPages("PAGE1").ClientSize.Height)
    3. Me.TabControl1.TabPages("PAGE1").DrawToBitmap(bm, Me.TabControl1.TabPages("PAGE1").ClientRectangle)
    4. GetImage1 = bm
    5. End Function
    6. Private Function GetImage2() As Bitmap
    7. Dim bm As New Bitmap(Me.TabControl1.TabPages("PAGE2").ClientSize.Width, Me.TabControl1.TabPages("PAGE2").ClientSize.Height)
    8. Me.TabControl1.TabPages("PAGE2").DrawToBitmap(bm, Me.TabControl1.TabPages("PAGE2").ClientRectangle)
    9. GetImage2 = bm
    10. End Function
    11. Private Sub Button5_Click(sender As System.Object, e As System.EventArgs) Handles Button5.Click
    12. If PrintDialog1.ShowDialog() = DialogResult.OK Then
    13. PagePrinting = 0
    14. PrintDocument1.Print()
    15. End If
    16. End Sub
    17. Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    18. If PagePrinting = 0 Then
    19. e.Graphics.DrawImage(GetImage1(), e.MarginBounds)
    20. Else
    21. e.Graphics.DrawImage(GetImage2(), e.MarginBounds)
    22. End If
    23. PagePrinting = PagePrinting + 1
    24. If PagePrinting = 2 Then e.HasMorePages = False Else e.HasMorePages = True
    25. End Sub


    Nach dem ich auf Drucken klicke und dann auf OK um zu starten kommt folgende Fehlermeldung: Jemand eine Lösung dazu?

    System.NullReferenceException wurde nicht behandelt.
    HResult=-2147467261
    Message=Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
    Source=Project1
    StackTrace:
    bei WindowsApplication1.Form3.GetImage1() in Pfad\Form3.vb:Zeile 58.
    bei WindowsApplication1.Form3.PrintDocument1_PrintPage(Object sender, PrintPageEventArgs e) in Pfad\Form3.vb:Zeile 78.
    bei System.Drawing.Printing.PrintDocument.OnPrintPage(PrintPageEventArgs e)
    bei System.Drawing.Printing.PrintDocument._OnPrintPage(PrintPageEventArgs e)
    bei System.Drawing.Printing.PrintController.PrintLoop(PrintDocument document)
    bei System.Drawing.Printing.PrintController.Print(PrintDocument document)
    bei System.Drawing.Printing.PrintDocument.Print()
    bei WindowsApplication1.Form3.Button5_Click(Object sender, EventArgs e) in Pfad\Form3.vb:Zeile 72.
    bei System.Windows.Forms.Control.OnClick(EventArgs e)
    bei System.Windows.Forms.Button.OnClick(EventArgs e)
    bei System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    bei System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    bei System.Windows.Forms.Control.WndProc(Message& m)
    bei System.Windows.Forms.ButtonBase.WndProc(Message& m)
    bei System.Windows.Forms.Button.WndProc(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    bei System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    bei System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    bei System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    bei System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
    bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
    bei WindowsApplication1.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:Zeile 81.
    bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
    bei System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
    bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
    bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
    bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
    bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
    bei System.Threading.ThreadHelper.ThreadStart()
    InnerException:
    Was sagt das andere Forum zu diesem Fehler? X(

    Akiju87 schrieb:

    bei WindowsApplication1.Form3.GetImage1() in Pfad\Form3.vb:Zeile 58.
    Offensichtlich gibt es da eine TabPage nicht unter der vorausgesetzten Bezeichnung.
    Setze einen Haltepunkt rein und überzeuge Dich davon, dass die angeforderte TabPage existiert.
    Gugst Du hier.
    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!
    Nun klappt es.. Vielen Dank :thumbsup:

    Ich musste echt schmunzeln und fühlte mich ertappt als ich deinen Beitrag zur Fehlerbehebung gelesen habe :whistling:

    Aber wenn man sich das erstmal so alles reinzieht an Informationen, denkt man sich so komplex ist das nicht.
    Das schafft man schon ^^

    Dann hat man so seine ersten Idden/vorstellung reingebracht und umgestzt.. Dann wirds doch kompliziert.
    Werde nun mein Chef mal nach einen Seminar bzw. Fortbildung - naja wohl eher Erstausbildung in meinem Fall :) fragen.

    nun wird noch ein wenig rumprobiert was die formatierung angeht ^^
    Ich muss doch noch mal nachfragen :|

    also ich habs ja nun hinbekommen das ich die beiden TabPages gedruckt bekomme.

    Nun habe ich das Problem das die nicht echtgröße gedruckt werden, sonden in Höhe und Breite gezogen.
    Wie kann ich das nuch hinbekommen das die Bilder der Tabs in Originalgröße gedruckt werden und nicht gezogen?

    Akiju87 schrieb:

    Originalgröße
    ist da nicht relevant, da diese in Pixeln angegeben wird.
    Du kannst dem Graphics-Objekt sagen, dass alle Abmessungen in Millimetern angegeben werden.
    Du kannst einem Image ein Ziel-Rectangle vorgeben, in dem es gedruckt wird.
    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!
    huhu. Ich nochmal. Ich habe nun ein Paar Tage weiter probiert.
    Nur wirklich weiter komme ich nicht.
    Ich habe nun eine Code gefunden:

    VB.NET-Quellcode

    1. Private Sub Button9_Click(sender As System.Object, e As System.EventArgs) Handles Button9.Click
    2. PrintForm1.PrintAction = Printing.PrintAction.PrintToPreview
    3. For i As Integer = 0 To Me.TabControl1.TabPages.Count - 1
    4. Me.TabControl1.TabPages(i).Show()
    5. PrintForm2.Print(Me, PowerPacks.Printing.PrintForm.PrintOption.ClientAreaOnly)
    6. Next
    7. End Sub


    Der Code soll eigentlich alle TabPages drucken. Da hier auf PrintToPreview gestellt ist zeigt er mir ja die Vorschau der jeweiligen zu druckende Seite an.

    Das Problem hier ist das er mir 3 mal dieselbe TabPage anzeigt und nicht Page1, 2 und 3.
    Irgendeine Idee was ich da falsch mache?
    @Akiju87 Sieh Dir mal diesen PowerPacks-freien Code an:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    3. Using dlg = New PrintPreviewDialog
    4. dlg.Document = Me.PrintDocument1
    5. dlg.ShowDialog()
    6. End Using
    7. End Sub
    8. Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    9. For i As Integer = 0 To Me.TabControl1.TabPages.Count - 1
    10. Me.TabControl1.SelectedIndex = i
    11. Using bmp As New Bitmap(Me.TabControl1.ClientRectangle.Width, Me.TabControl1.ClientRectangle.Height)
    12. Me.TabControl1.DrawToBitmap(bmp, Me.TabControl1.ClientRectangle)
    13. e.Graphics.DrawImage(bmp, 10, 10 + bmp.Height * i)
    14. End Using
    15. Next
    16. End Sub
    17. End Class

    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!

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

    Hmm.. Bei deinem Beispiel druckt er mir nur die TabPages untereinander. Seite 2 wird dabei abgeschnitten, jedoch nicht auf Seite 2 weiter gedruckt. Jetzt muss ich mal schauen das ich sage das nach TabPage1 eine neue Seite angesprochen werden soll.

    Ich glaube ich habe gerade ein Brett vorm Kopf.