I have a WPF application with a custom control, based on DocumentViewer. There is a "Print" button, which leads to printer selection dialog. When I select a certain printer ("novaPDF Lite Server v7") and then press the "Print" button, a dialog box with printer settings is displayed. That dialog box appears in the task bar as a separate application.
When I activate that printer dialog, then activate some other application and then switch back to the WPF application, its client are (everything below the title bar) is white. It looks as if it hangs.
When I close the printer settings dialog, the WPF application starts to look in the normal way (all the controls are there).
I suppose that the problem is caused by the way the print process is started. Maybe it can fixed by doing the printing in a separate thread.
Here's how it is done now:
using System.Printing;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
namespace MyControls
{
public class MyDocumentViewer : DocumentViewer
{
[...]
protected override void OnPrintCommand()
{
base.OnPrintCommand();
this.FirePrintFinished();
}
[...]
}
What can I do in order to fix the problem?
Update 1 (03.09.2013): Changing the MyDocumentViewer
so that printing is done asynchronously didn't help.
namespace MyControls
{
public class MyDocumentViewer : DocumentViewer
{
[...]
protected override void OnPrintCommand()
{
var worker = new PrintWorker(this);
Dispatcher.Invoke(new Action(worker.DoWork));
}
public void OnPrintCommandBase()
{
base.OnPrintCommand();
}
[...]
}
public class PrintWorker
{
private readonly MyDocumentViewer _myDocumentViewer;
public PrintWorker(MyDocumentViewer myDocumentViewer)
{
_myDocumentViewer = myDocumentViewer;
}
public void DoWork()
{
_myDocumentViewer.OnPrintCommandBase();
_myDocumentViewer.FirePrintFinished();
}
}
}
Update 2 (05.09.2013): The problem can only be reproduced, when I access the machine with the application via Remote Desktop (it does not occur, if I run the program locally).
Dispatcher
is here to run a delegate in the UI thread,Dispatcher.Invoke()
will run a delegate synchronously on the thread the Dispatcher is associated with (see msdn).What you need may be
Dispatcher.BeginInvoke()
, or you should even useBackgroundWorker
class to have a real background operation.I'd also recommend you using
Application.Current.Dispatcher
(see this question: Dispatcher.CurrentDispatcher vs. Application.Current.Dispatcher)