Print von mehreren Seiten

  • C#
  • .NET (FX) 1.0–2.0

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von King2k7.

    Print von mehreren Seiten

    Ich versuche gerade die Einträge aus einem Listview zu drucken. Das ganze klappt auch wunderbar, bis die Einträge länger sind als eine A4 Seite.
    Ich bekomme es nicht hin, bzw. weiß nicht genao wo ich bei meinem Code die Abfrage einbauen soll ob die zu druckenden Einträge länger sind als die Seite?

    Zur Erkläreung ich habe in einem Listview verschiedene Gruppen. Und möchte zuerst den Gruppennamen und darunter die Einträge die zu dieser Gruppe gehören drucken.
    Dazu durchlaufe ich die Gruppen und und überprüfe ob das Listviewitem der Gruppe angehört.

    Wie genau stelle ich es am besten an zu überprüfen wann eine 2. Seite angefangen werden muss?

    C#-Quellcode

    1. private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    2. {
    3. //int i = 0;
    4. int h = 80;
    5. // int y = 20;
    6. e.Graphics.DrawString("Rezeptanforderung " + Properties.Settings.Default.wohnbereich + " vom " + System.DateTime.Now.ToShortDateString(), new Font("Calibri ", 15, FontStyle.Bold), Brushes.Black, 50, 50);
    7. foreach (ListViewGroup g in listView1.Groups)
    8. {
    9. e.Graphics.DrawString(g.ToString(), new Font("Calibri ", 12, FontStyle.Bold), Brushes.Black, 50, h);
    10. foreach (ListViewItem item in listView1.Items)
    11. {
    12. if (item.Checked && item.Group.ToString() == g.ToString() )//&& i < listView1.CheckedItems.Count)
    13. {
    14. e.Graphics.DrawString("- "+item.Text, new Font("Calibri ", 10, FontStyle.Regular), Brushes.Black, 50, h + 20);
    15. if (item.SubItems[1].Text != "")
    16. {
    17. h += 15;
    18. e.Graphics.DrawString("Bemerkung:" + item.SubItems[1].Text, new Font("Calibri ", 9, FontStyle.Regular), Brushes.Black, 50, h + 20);
    19. }
    20. h += 15;
    21. }
    22. h += 35;
    23. }
    24. e.Graphics.DrawString("__________________________", new Font("Calibri ", 9, FontStyle.Regular), Brushes.Black, 50, h+35);
    25. e.Graphics.DrawString("Unterschrift Wohnbereich", new Font("Calibri ", 9, FontStyle.Regular), Brushes.Black, 50, h + 55);
    26. }
    Schau mal ob dir das hilft: Drucken mehrseitiger Dokumente
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    @King2k7 Du machst einen "trockenen Probedruck" ohne die Druckausgabe selbst und misst dabei die Zeilenhöhen aus.
    Das ist insbesondere dann wichtig, wenn Gruppen von Zeilen nicht getrennt werden sollen.
    Wenn die Ziel-Seitenhöhe überschritten wurde, brichst Du das ganze ab und druckst "scharf" und fängst neu auf der nächsten Seite wieder an.
    Ansonsten hat Dir @mrMo ja schon den richtigen Link gepostet.
    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!

    King2k7 schrieb:

    die variable h
    Ja.
    Du kannst ja die Papiergröße und den Print-Bereich abfragen und weißt dann genau, wann Schluss ist.
    Du musst Dir dann nur merken, wo es mit der nächsten Seite weiter geht.
    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!
    Also ich habe meinen Code umgeschrieben, leider fehlt noch ein wenig zum Eerfolg. Sobald das Seitenende der 1. Seite erreicht ist wird statt auf Seite 2, einfach auf Seite 1 oben weitergedruckt.
    Ich dachte das mit dem Event "e.HasMorePages = true;" auf eine 2. Seite gedruckt wird, dies ist aber nicht der Fall. Wie genau bekomm ich es hin das auf Seite 2 und nicht wieder auf Seite 1 gedruckt wird?

    Hier mal mein Code:
    Spoiler anzeigen

    C#-Quellcode

    1. private void button1_Click(object sender, EventArgs e)
    2. {
    3. printDialog1.Document = printDocument1;
    4. if (printDialog1.ShowDialog()==DialogResult.OK)
    5. {
    6. i = 0;
    7. printDocument1.Print();
    8. }
    9. }
    10. private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    11. {
    12. ArrayList CountedLines = CountLines();//Funktion um alle Listvieitems in eine Arraylist zu schreiben, die dann mit der while Schleife durchlaufen wird.
    13. Graphics graphic = e.Graphics;
    14. SolidBrush brush = new SolidBrush(Color.Black);
    15. Font font = new Font("Courier New", 11);
    16. float pageWidth = e.PageSettings.PrintableArea.Width;
    17. float pageHeight = e.PageSettings.PrintableArea.Height;
    18. float fontHeight = font.GetHeight();
    19. int startX = 40;
    20. int startY = 30;
    21. int offsetY = 40;
    22. while (i < CountedLines.Count)
    23. {
    24. graphic.DrawString(CountedLines[i].ToString(), font, brush, startX, startY + offsetY);
    25. offsetY += (int)fontHeight;
    26. if (offsetY >= pageHeight)
    27. {
    28. e.HasMorePages = true;
    29. offsetY = 40;
    30. return;
    31. }
    32. else
    33. {
    34. e.HasMorePages = false;
    35. }
    36. i++;
    37. }
    38. }

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

    HasMorePages führt nur dazu, dass der PrintPage-EventHandler nochmal aufgerufen wird. Es liegt aber an Dir dafür zu sorgen, dass in dem EventHandler seitenabhängig gedruckt wird. Das heißt, dass Du sagen musst:
    Wenn Seitenindex = 0, dann druckte dies.
    Wenn Seitenindex = 1, dann druckte das.

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @King2k7 Das tut genau was es soll.
    Ich hab Dir mal noch ne Seitennummer reingebaut:
    Spoiler anzeigen

    C#-Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Drawing;
    4. using System.Windows.Forms;
    5. namespace WindowsFormsApplication1
    6. {
    7. public partial class Form1 : Form
    8. {
    9. private List<int> CountedLines;
    10. private int Index;
    11. private int Page;
    12. public Form1()
    13. {
    14. InitializeComponent();
    15. }
    16. private void button1_Click(object sender, EventArgs e)
    17. {
    18. using (PrintPreviewDialog dlg = new PrintPreviewDialog())
    19. {
    20. dlg.Document = this.printDocument1;
    21. dlg.ShowDialog();
    22. }
    23. }
    24. private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    25. {
    26. Index = 0;
    27. Page = 1;
    28. CountedLines = new List<int>();
    29. for (int i = 0; i < 150; i++)
    30. {
    31. CountedLines.Add(i + 1);
    32. }
    33. }
    34. private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    35. {
    36. Graphics graphic = e.Graphics;
    37. SolidBrush brush = new SolidBrush(Color.Black);
    38. Font font = new Font("Courier New", 11);
    39. float fontHeight = font.GetHeight();
    40. int startX = 40;
    41. int startY = 30;
    42. int offsetY = 40;
    43. float pageWidth = e.PageSettings.Bounds.Width;
    44. float pageHeight = e.PageSettings.Bounds.Height - e.PageSettings.Margins.Bottom;
    45. graphic.DrawString("Seite " + Page, font, brush, startX, startY);
    46. Page += 1;
    47. while (Index < CountedLines.Count)
    48. {
    49. graphic.DrawString(CountedLines[Index].ToString(), font, brush, startX, startY + offsetY);
    50. offsetY += (int)fontHeight;
    51. if (offsetY >= pageHeight)
    52. {
    53. e.HasMorePages = true;
    54. return;
    55. }
    56. Index++;
    57. }
    58. }
    59. }
    60. }
    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!
    @RodFromGermany: Es tut mir leid, ich verstehe es noch immer nicht. Es wird immer auf die 1. Seite erneut gedruckt. Habe mir auch mehr als eine Anleitung angeschaut.
    Ich versteh es soweit das der print läuft bis die Seitenhöhe erreicht wurde und dann HasMorePages=true dafür sorgt dass das Print Event von vorne läuft.
    Ich kann aber nicht nachvollziehen wie genau ich dem Programm sagen soll das es auf Seite 2 weitergeht.

    King2k7 schrieb:

    Es wird immer auf die 1. Seite erneut gedruckt.
    Bei mir nicht:
    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!

    King2k7 schrieb:

    Ich kann aber nicht nachvollziehen wie genau ich dem Programm sagen soll das es auf Seite 2 weitergeht.

    VaporiZed schrieb:

    Das heißt, dass Du sagen musst:
    Wenn Seitenindex = 0, dann druckte dies.
    Wenn Seitenindex = 1, dann druckte das.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Also es klappt jetzt, lag an einer Zeile die ich vergessen hatte zu löschen.

    Das heißt, dass Du sagen musst:
    Wenn Seitenindex = 0, dann druckte dies.
    Wenn Seitenindex = 1, dann druckte das.

    Ja das ist im Prinzip verstanden. Aber z.B. im Code von RodFromGermany wurde einfach ein globales Int Page deklariert, dieses wird hochgezählt. Aber es ist ja einfach erstmal "irgend" ein Int. Wieso weiß die Print Funktion das es jetzt Seite 2 drucken muss? Wo wurde die Beziehung zwischen dem Int Page und der Seitenanzahl hergestellt?

    Oder stehe ich gerade echt so auf dem Schlauch?
    Am Ende des PrintPage-EventHandlers (oder bei RfGs Code irgendwo dazwischen) steht Page += 1. Wie und wann Du diesen selbstangelegten PageCounter hochzählst, bleibt Dir überlassen. Das PrintDocument selber weiß herzlich wenig von alldem. Da wird wohl nur intern gesagt:

    C#-Quellcode

    1. do
    2. {
    3. e.HasMorePages = false;
    4. FeuereDasPrintPageEvent(this, e);
    5. } while (e.HasMorePages);

    Das heißt, dass Du Dich selber um Seitenzahlen, deren Hochzählen und den seitenabhängigen Inhalt kümmern musst. Das PrintDocument selber ruft den EventHandler nur solange auf, bis Du festlegst, das e.HasMorePages auf false gestellt ist/bleibt.
    Oder eben krasses Gegenbeispiel:

    C#-Quellcode

    1. private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    2. {
    3. e.HasMorePages = true;
    4. }

    Das wird dazu führen, dass der EventHandler bis zum Sankt-Nimmerleinstag aufgerufen wird. Aber auf welcher Seite Du bist, weiß das PrintDocument nicht. Das ist Deine Aufgabe.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    @King2k7 Du musst wissen, dass das PrintPage-Event für jede einzelne Seite vom Framework erneut aufgerufen wird.

    King2k7 schrieb:

    Wieso weiß die Print Funktion das es jetzt Seite 2 drucken muss?
    Im BeginPrint-Event wird der Seitenzähler initialisiert.
    In PrintPage wird nach dem Drucken der Seitenzahl der Seitenzähler inkrementiert.
    Der Seitenzähler zeigt also stets die Nummer der bedruckten Seite an. Die Reihenfolge hier in meinem Beispiel nicht optimal.
    Also:
    Wenn Du im BeginPrint-Event den Seitenzähler zu 0 setzt
    und
    wenn Du den Seitenzähler im PrintPage-Event vor dem Drucken der Seitenzahl inkrementierst hat der Seitenzähler danach stets den aktuellen Wert.
    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“ ()