Click here to Skip to main content
15,894,291 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi. i am trying to print richtextbox content. all works fine with small text, but if text is very large, the ui frezes for a long time, while text is not saved to memory stream. here is the code for print:
C#
public static void PrintDocument(RichTextBox rtb)
{
    TextRange doc = new TextRange(rtb.Document.ContentStart, rtb.Document.ContentEnd);

    MemoryStream ms = new MemoryStream();
    range.Save(ms, DataFormats.Rtf);

    FlowDocument flowDocumentCopy = new FlowDocument();
    TextRange copyDocumentRange = new TextRange(flowDocumentCopy.ContentStart, flowDocumentCopy.ContentEnd);
    copyDocumentRange.Load(ms, DataFormats.Rtf);

    // Create a XpsDocumentWriter object, open a Windows common print dialog.
    // This methods returns a ref parameter that represents information about the dimensions of the printer media.
    PrintDocumentImageableArea ia = null;
    XpsDocumentWriter docWriter = PrintQueue.CreateXpsDocumentWriter(ref ia);

    if (docWriter != null && ia != null)
    {
        DocumentPaginator paginator = ((IDocumentPaginatorSource)flowDocumentCopy).DocumentPaginator;

        // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
        paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight);
        Thickness pagePadding = flowDocumentCopy.PagePadding;
        flowDocumentCopy.PagePadding = new Thickness(
                Math.Max(ia.OriginWidth, pagePadding.Left),
                Math.Max(ia.OriginHeight, pagePadding.Top),
                Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), pagePadding.Right),
                Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), pagePadding.Bottom));
        flowDocumentCopy.ColumnWidth = double.PositiveInfinity;

        // Send DocumentPaginator to the printer.
        docWriter.Write(paginator);
    }
}

so, if text is very huge, range.Save(ms, DataFormats.Rtf); takes a lot of time. i tryed to make some changes, but they do not work properly:
so, i changed PrintDocument method:
C#
public static void PrintDocument(MemoryStream ms)
       {
           FlowDocument flowDocumentCopy = new FlowDocument();
           TextRange copyDocumentRange = new TextRange(flowDocumentCopy.ContentStart, flowDocumentCopy.ContentEnd);
           copyDocumentRange.Load(ms, DataFormats.Rtf);
           ..
       }

and in window added a background worker:
C#
void printWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            PrintManager.PrintDocument(e.Result as MemoryStream);
        }
        void printWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            MemoryStream result = new MemoryStream();
            FlowDocument doc = e.Argument as FlowDocument;
            TextRange text = new TextRange(doc.ContentStart, doc.ContentEnd);
            text.Save(result, DataFormats.Rtf);
            e.Result = result;
        }

and i call it, when i click print button:
C#
private void printBtn_OnButtonClick(object sender, EventArgs e)
        {
            if (printWorker.IsBusy)
                return;
            printWorker.RunWorkerAsync(wordsResultBox.Document);
        }

when i launch it, i get the InvalidOperationException (The calling thread can not access this object because the owner of this object is the other thread) at line
C#
text.Save(result, DataFormats.Rtf);
in printWorker_DoWork method. any ideas how it can be fixed or how i can print large text without freezing the ui?
Posted

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900