gpt4 book ai didi

wpf - 在不同的 UI 线程中打印 DocumentViewer 的内容

转载 作者:行者123 更新时间:2023-12-04 17:56:47 25 4
gpt4 key购买 nike

在我的 WPF 应用程序中,我有特定的 Window除了其他控件之外,它还包含 DocumentViewer .

打开并加载此窗口时,它会动态构建 FixedDocument带有进度指示器,然后在 DocumentViewer 中显示.它有效,并且为了改善用户体验,我在自己的线程中运行此窗口,以便在构建文档时主应用程序窗口仍然响应。

基于 this web page 的提示,我在这样的新线程中打开我的窗口:

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;amp; writer, PrintTicket&amp;amp; partialTrustPrintTicket, PrintQueue&amp;amp; partialTrustPrintQueue, Double&amp;amp; width, Double&amp;amp; height, String jobDescription)
at System.Printing.PrintQueue.CreateXpsDocumentWriter(String jobDescription, PrintDocumentImageableArea&amp;amp; documentImageableArea)
at System.Windows.Controls.Primitives.DocumentViewerBase.OnPrintCommand()
at System.Windows.Controls.Primitives.DocumentViewerBase.ExecutedRoutedEventHandler(Object target, ExecutedRoutedEventArgs args)
...

我的预感是打印对话框正在主 UI 线程中打开,并试图访问由我自己的线程创建和拥有的文档,因此崩溃了。

有什么想法可以解决这个问题吗?我想将窗口保留在自己的线程中。

最佳答案

在谷歌搜索之后,我偶然发现了以下线程,这似乎是我遇到的确切问题。

PrintDialog and a secondary UI thread severe problem

在那个线程中,这个家伙最终使用了一个自定义的 PrintDialog 类(可以找到它的源代码 here),它与内置的 PrintDialog 非常相似,但有一些调整来修复这些跨线程错误(以及它还覆盖了 XPS Document Writer,后者显然将自身与应用程序的主 UI 线程更紧密地联系在一起)

我复制并粘贴了该自定义 PrintDialog 的代码(并将该类重命名为 ThreadSafePrintDialog ),删除了我的 Print 按钮的 CommandTarget,而是使用我自己的 Print 方法:

private void Print_Executed(object sender, ExecutedRoutedEventArgs args) {
var printDialog = new ThreadSafePrintDialog();
if (!printDialog.ShowDialog(this)) return;

printDialog.PrintDocument(DocumentViewer.Document.DocumentPaginator, "My Document");
}

完美运行。

关于wpf - 在不同的 UI 线程中打印 DocumentViewer 的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7335507/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com