Print RichTextBox mail merge letters in background thread

6 posts, 0 answers
  1. Nisarg
    Nisarg avatar
    25 posts
    Member since:
    Dec 2011

    Posted 10 Jan Link to this post

    Hi,

    I want to print all mail merge letters (around 500 to 800) in background thread so that my application remains active and I should continue
    doing tasks when the printing is in progress.
     
    I also want to perform database task on all letters with the printing process in my application
    but when I print all generated mail merge letters, my application is freezing until the printing is completed.

    I also created support ticket no 999572.

    Is it also possible to cancel printing process in the middle after printing is started?

    Thanks

  2. Tanya
    Admin
    Tanya avatar
    405 posts

    Posted 11 Jan Link to this post

    Hello Nisarg,

    I am attaching the modified version of the sample project to show how a similar scenario could be implemented. It demonstrates how you could use the Thread class to perform background mail merge and print the result. Here are some notes regarding the implementation:

    • In order to print RadRichTextBox, it must be included in the visual tree. Therefore, an additional Window is created to hold the RadRichTextBox instance.
    • When working in another thread, you may experience issues when the document contains images. I included the necessary code, which will freeze all the images in the document and will prevent this.
    • In the project is demonstrated how you could stop the process as well. It is done in the handler of the button with text "Stop Printing".
    • In case you need to notify the UI about the progress of the operations, you could use the BeginInvoke() method of the Dispatcher:
    • this.Dispatcher.BeginInvoke(new Action(() => ... );

    Hope this helps.
     
    Regards,
    Tanya
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for WPF is Visual Studio 2017 Ready
  4. Nisarg
    Nisarg avatar
    25 posts
    Member since:
    Dec 2011

    Posted 12 Jan Link to this post

    Hi Tanya,

    Thanks for your reply.

    MailMergePrintingDemo is working fine. I do not want to use default printer but
    I would like to select printer from all available printer (by PrintDialog) before starting to print in background thread.

    When I use PrintDialog.ShowDialog() method in the background thread, it throws an error
    "An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll
    Additional information: The calling thread cannot access this object because a different thread owns it."

    So how can I select printers from available printer options when I want to print in background thread?

    Thanks

  5. Tanya
    Admin
    Tanya avatar
    405 posts

    Posted 15 Jan Link to this post

    Hello Nisarg,

    It is not allowed to show dialogs or other elements from the background thread to the UI. To achieve the desired goal, you could use the Dispatcher.Invoke() method. This method will give you access to the UI thread and you will be able to show the dialog. When the dialog is shown you can get the selected printer name through the PrintQueue.FullName property and pass it as a parameter to the print action:
    this.Dispatcher.Invoke(() =>
    {
        bool? dialogResult = dialog.ShowDialog();
        if (dialogResult.Value)
        {
            printerName = dialog.PrintQueue.FullName;
        }
    });
     
     
    this.printAction(result, printerName);

    Here is how I changed its declaration to pass the new parameter:
    private Action<RadDocument, string> printAction = new Action<RadDocument, string>((doc, printerName) =>
    { ... }

    Before start printing on the background thread, a new PrintDialog should be created. The following snippet demonstrates how you could set the name of the printer to be used:
    PrintDialog printDialog = new PrintDialog();
    PrintQueue queue = new LocalPrintServer().GetPrintQueue(printerName);
    printDialog.PrintQueue = queue;

    You could follow the same approach for any other option that should be set from the user through the dialog.

    Regards,
    Tanya
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Nisarg
    Nisarg avatar
    25 posts
    Member since:
    Dec 2011

    Posted 21 Jan Link to this post

    Hi Tanya,

    When I try to get PrintQueue by printerName at this point - "PrintQueue queue = new LocalPrintServer().GetPrintQueue(printerName);"
    I got below error.
    An exception occurred while populating the properties for the PrintQueue object. Win32 error: The printer name is invalid.

    I am using network printer to print document from the background thread.

    Can you please advise or suggest the solution?

    Thanks
  7. Tanya
    Admin
    Tanya avatar
    405 posts

    Posted 26 Jan Link to this post

    Hello Nisarg,

    This is a low-level exception in the .NET Framework and could be just skipped. If you continue the execution of the application, everything should work as expected. In order to suppress this exception you could go to Debug -> Exceptions and uncheck the check box for CLR Exceptions.

    You could find a similar discussion in this thread on StackOverflow.

    Regards,
    Tanya
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for WPF is Visual Studio 2017 Ready