2011-09-13 39 views
11

voglio stampare il contenuto della mia RichTextBox (eintragRichTextBox) che ho ora questo codice:C# Printing (RichTextBox)

private void druckenPictureBox_Click(object sender, EventArgs e) 
{ 
    PrintDialog printDialog = new PrintDialog(); 
    PrintDocument documentToPrint = new PrintDocument(); 
    printDialog.Document = documentToPrint; 

    if (printDialog.ShowDialog() == DialogResult.OK) 
    { 
     StringReader reader = new StringReader(eintragRichTextBox.Text); 
     documentToPrint.Print(); 
     documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage); 
    } 
} 

private void DocumentToPrint_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) 
{ 
    StringReader reader = new StringReader(eintragRichTextBox.Text); 
    float LinesPerPage = 0; 
    float YPosition = 0; 
    int Count = 0; 
    float LeftMargin = e.MarginBounds.Left; 
    float TopMargin = e.MarginBounds.Top; 
    string Line = null; 
    Font PrintFont = this.eintragRichTextBox.Font; 
    SolidBrush PrintBrush = new SolidBrush(Color.Black); 

    LinesPerPage = e.MarginBounds.Height/PrintFont.GetHeight(e.Graphics); 

    while (Count < LinesPerPage && ((Line = reader.ReadLine()) != null)) 
    { 
     YPosition = TopMargin + (Count * PrintFont.GetHeight(e.Graphics)); 
     e.Graphics.DrawString(Line, PrintFont, PrintBrush, LeftMargin, YPosition, new StringFormat()); 
     Count++; 
    } 

    if (Line != null) 
    { 
     e.HasMorePages = true; 
    } 
    else 
    { 
     e.HasMorePages = false; 
    } 
    PrintBrush.Dispose(); 
} 

Ma mi stampe sempre un sito vuoto :(.. Qualcuno ha un'idea, il motivo per cui non funziona Or dispone di qualcuno un codice migliore/idea di come avrei potuto ottenere la stampa

EDIT:?? sguardo risposta

+0

perché stai creando questo: "Lettore StringReader ..." prima del documentoToPrint.Print()? Penso che tu non ne abbia bisogno lì. Aso, cosa succede quando esegui il debug? –

+0

Non ho ancora individuato il tuo problema, ma una cosa è che se la tua RTB ha abbastanza testo da riempire più di una pagina, scoprirai che stampa un numero infinito di pagine. Devi dichiarare i tuoi valori Reader, Count e Line al di fuori dell'ambito dell'evento PrintPage ... devi anche eseguire un debug, aggiungere alcuni punti di interruzione e vedere quali valori vengono impostati come previsto e quali non lo sono – musefan

+0

http://support.microsoft.com/kb/812425 –

risposta

5

ce l'ha ..

su questo luogo:

if (printDialog.ShowDialog() == DialogResult.OK) 
{ 
    StringReader reader = new StringReader(eintragRichTextBox.Text); 
    documentToPrint.Print(); 
    documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage); 
} 

ho cambiato:

if (printDialog.ShowDialog() == DialogResult.OK) 
{ 
    StringReader reader = new StringReader(eintragRichTextBox.Text); 
    documentToPrint.PrintPage += new PrintPageEventHandler(DocumentToPrint_PrintPage); 
    documentToPrint.Print();  
} 

Ora funziona bene ..

Anche se qualcuno ha bisogno di stampare il contenuto di un RichTextBox, è possibile utilizzare il mio codice ..

+0

Questo non stampa il documento con stile e richiede molto tempo per stampare un lungo testo! –

+0

Ho scritto questo codice 4 anni fa e l'obiettivo non era quello di stamparlo con stile. Comunque grazie per aver fornito una nuova variante nelle risposte. – eMi

0

Sembra che il tuo codice abbia un problema, ristampa la prima pagina solo a causa dello

StringReader reader = new StringReader(eintragRichTextBox.Text); 

nel vostro DocumentToPrint_PrintPage()

0

uso che!

StringReader reader; 
     int prov = 0; 

     private void DocumentToPrint_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) 
     { 


      if (prov == 0) 
      { 
       prov = 1; 
       reader = new StringReader(eintragRichTextBox.Text); 
      } 
float LinesPerPage = 0; 
      float YPosition = 0; 
      int Count = 0; 
      float LeftMargin = e.MarginBounds.Left; 
      float TopMargin = e.MarginBounds.Top; 
      string Line = null; 

....

5

ho provato How to print the content of a RichTextBox control e funziona come un fascino.

Devi solo creare un numero personalizzato RichTextBox e poi stamperà tutto il testo così velocemente e manterrà lo stile anche sulla carta!

codice personalizzato per la creazione di RichTextBox

using System; 
using System.Windows.Forms; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Drawing.Printing; 

namespace RichTextBoxPrintCtrl 
{ 
    public class RichTextBoxPrintCtrl:RichTextBox 
    { 
     //Convert the unit used by the .NET framework (1/100 inch) 
     //and the unit used by Win32 API calls (twips 1/1440 inch) 
     private const double anInch = 14.4; 

     [StructLayout(LayoutKind.Sequential)] 
      private struct RECT 
     { 
      public int Left; 
      public int Top; 
      public int Right; 
      public int Bottom; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
      private struct CHARRANGE 
     { 
      public int cpMin;   //First character of range (0 for start of doc) 
      public int cpMax;   //Last character of range (-1 for end of doc) 
     } 

     [StructLayout(LayoutKind.Sequential)] 
      private struct FORMATRANGE 
     { 
      public IntPtr hdc;    //Actual DC to draw on 
      public IntPtr hdcTarget;  //Target DC for determining text formatting 
      public RECT rc;    //Region of the DC to draw to (in twips) 
      public RECT rcPage;   //Region of the whole DC (page size) (in twips) 
      public CHARRANGE chrg;   //Range of text to draw (see earlier declaration) 
     } 

     private const int WM_USER = 0x0400; 
     private const int EM_FORMATRANGE = WM_USER + 57; 

     [DllImport("USER32.dll")] 
     private static extern IntPtr SendMessage (IntPtr hWnd , int msg , IntPtr wp, IntPtr lp); 

     // Render the contents of the RichTextBox for printing 
     // Return the last character printed + 1 (printing start from this point for next page) 
     public int Print(int charFrom, int charTo,PrintPageEventArgs e) 
     { 
      //Calculate the area to render and print 
      RECT rectToPrint; 
      rectToPrint.Top = (int)(e.MarginBounds.Top * anInch); 
      rectToPrint.Bottom = (int)(e.MarginBounds.Bottom * anInch); 
      rectToPrint.Left = (int)(e.MarginBounds.Left * anInch); 
      rectToPrint.Right = (int)(e.MarginBounds.Right * anInch); 

      //Calculate the size of the page 
      RECT rectPage; 
      rectPage.Top = (int)(e.PageBounds.Top * anInch); 
      rectPage.Bottom = (int)(e.PageBounds.Bottom * anInch); 
      rectPage.Left = (int)(e.PageBounds.Left * anInch); 
      rectPage.Right = (int)(e.PageBounds.Right * anInch); 

      IntPtr hdc = e.Graphics.GetHdc(); 

      FORMATRANGE fmtRange; 
      fmtRange.chrg.cpMax = charTo;    //Indicate character from to character to 
      fmtRange.chrg.cpMin = charFrom; 
      fmtRange.hdc = hdc;     //Use the same DC for measuring and rendering 
      fmtRange.hdcTarget = hdc;    //Point at printer hDC 
      fmtRange.rc = rectToPrint;    //Indicate the area on page to print 
      fmtRange.rcPage = rectPage;   //Indicate size of page 

      IntPtr res = IntPtr.Zero; 

      IntPtr wparam = IntPtr.Zero; 
      wparam = new IntPtr(1); 

      //Get the pointer to the FORMATRANGE structure in memory 
      IntPtr lparam= IntPtr.Zero; 
      lparam = Marshal.AllocCoTaskMem(Marshal.SizeOf(fmtRange)); 
      Marshal.StructureToPtr(fmtRange, lparam, false); 

      //Send the rendered data for printing 
      res = SendMessage(Handle, EM_FORMATRANGE, wparam, lparam); 

      //Free the block of memory allocated 
      Marshal.FreeCoTaskMem(lparam); 

      //Release the device context handle obtained by a previous call 
      e.Graphics.ReleaseHdc(hdc); 

      //Return last + 1 character printer 
      return res.ToInt32(); 
     } 

    } 
} 

La fonte principale comprende PrintDialog, PrintPreviewDialog, PrintDocument, and PageSetupDialog, ma funziona bene solo con un PrintDocument controllo. Quindi ho rimosso alcuni codici extra solo per abbreviare la parte utile. Ma se sei interessato a usarli tutti, puoi trovare il codice completo nella pagina collegata.

private PrintDocument _printDocument = new PrintDocument(); 
    private int _checkPrint; 
    public Form1() 
    { 
     InitializeComponent(); 
     _printDocument.BeginPrint += _printDocument_BeginPrint; 
     _printDocument.PrintPage += _printDocument_PrintPage; 
    } 

    private void btnPrint_Click(object sender, EventArgs e) 
    { 
     PrintDialog printDialog=new PrintDialog(); 
     if (printDialog.ShowDialog() == DialogResult.OK) 
      _printDocument.Print(); 
    } 

    private void _printDocument_PrintPage(object sender, PrintPageEventArgs e) 
    { 
     // Print the content of RichTextBox. Store the last character printed. 
     _checkPrint = rchEditor.Print(_checkPrint, rchEditor.TextLength, e); 

     // Check for more pages 
     e.HasMorePages = _checkPrint < rchEditor.TextLength; 
    } 

    private void _printDocument_BeginPrint(object sender, PrintEventArgs e) 
    { 
     _checkPrint = 0; 
    }