在我的 WPF 应用程序中,我有特定Window
的包含,除其他控件外,一个DocumentViewer
.
打开并加载此窗口时,它会动态构建一个FixedDocument
带有进度指示器的窗口,然后将其显示在DocumentViewer
. 它可以工作,并且为了改善用户体验,我在自己的线程中运行此窗口,以便在构建文档时主应用程序窗口仍然响应。
根据此网页上的提示,我在一个新线程中打开我的窗口,如下所示:
public void ShowDocumentViewerWindow(params object[] data) {
var thread = new Thread(() => {
var window = new MyDocumentViewerWindow(new MyObject(data));
window.Closed += (s, a) => window.Dispatcher.InvokeShutdown();
window.Show();
System.Windows.Threading.Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
到目前为止,我对这个设置很满意,但我遇到了一个问题。
MyDocumentViewerWindow
包含一个打印按钮,它引用了针对 DocumentViewer 的内置打印命令:
<Button Command="Print" CommandTarget="{Binding ElementName=MyDocumentViewer}">Print</Button>
在我将窗口放在自己的线程中之前,这工作得很好。但是现在,当我单击它时,应用程序崩溃了。Visual Studio 2010 突出显示上述代码中的以下行作为崩溃位置,并显示消息“调用线程无法访问此对象,因为不同的线程拥有它。':
System.Windows.Threading.Dispatcher.Run();
堆栈跟踪开始如下:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at MS.Internal.Printing.Win32PrintDialog.ShowDialog()
at System.Windows.Controls.PrintDialog.ShowDialog()
at System.Printing.PrintQueue.GatherDataFromPrintDialog(PrintDialog printDialog, XpsDocumentWriter&amp; writer, PrintTicket&amp; partialTrustPrintTicket, PrintQueue&amp; partialTrustPrintQueue, Double&amp; width, Double&amp; height, String jobDescription)
at System.Printing.PrintQueue.CreateXpsDocumentWriter(String jobDescription, PrintDocumentImageableArea&amp; documentImageableArea)
at System.Windows.Controls.Primitives.DocumentViewerBase.OnPrintCommand()
at System.Windows.Controls.Primitives.DocumentViewerBase.ExecutedRoutedEventHandler(Object target, ExecutedRoutedEventArgs args)
...
我的预感是打印对话框正在主 UI 线程中打开,并试图访问由我自己的线程创建和拥有的文档,因此崩溃了。
有什么想法可以解决这个问题吗?我想将窗口保留在自己的线程中。