我需要使用wpf UI元素如FixedDocument、FlowDocument、PageContent、BlockUIContainer等生成一个长的打印预览。为了保持我的UI响应,我正在使用一个单独的Thread类线程完成这部分工作(BackgroundWorker不起作用,因为我需要一个STA线程)。到目前为止一切都很好。
但是,在显示打印预览后,现在我需要打印,点击生成的预览上的打印图标会抛出臭名昭著的“调用线程无法访问此对象,因为不同线程拥有它”异常。那么,有什么解决办法吗?
但是,在显示打印预览后,现在我需要打印,点击生成的预览上的打印图标会抛出臭名昭著的“调用线程无法访问此对象,因为不同线程拥有它”异常。那么,有什么解决办法吗?
编辑(代码):
Dispatcher.CurrentDispatcher.Invoke(new Action(() =>
{
Thread thread = new Thread(() =>
{
FixedDocument document = renderFlowDocumentTemplate(report);
PrintPreview preview = new PrintPreview();
preview.WindowState = WindowState.Normal;
preview.documentViewer.Document = document;
preview.ShowDialog();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}));`
好的,RenderFlowDocumentTemplate()方法生成打印预览(包含UI元素),并使用报表数据填充它们。PrintPreview是一个自定义窗口,包含一个DocumentViewer元素,实际上持有和显示预览,并包含打印图标,点击该图标后我应该会得到打印对话框。
编辑(XAML):
<cw:CustomWindow x:Class="MyApp.Reports.PrintPreview"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cw="clr-namespace:MyApp.UI.CustomWindows;assembly=MyApp.UI.CustomWindows">
<DocumentViewer Margin="0,30,0,0" Name="documentViewer"></DocumentViewer>
</cw:CustomWindow>`