我需要使用诸如 FixedDocument、FlowDocument、PageContent、BlockUIContainer 之类的 wpf UI 元素生成打印预览(一个长的)。为了保持我的 UI 响应,我在一个单独的 Thread 类线程上做这部分(BackgroundWorker 将无法工作,因为我需要一个 STA 线程)。到目前为止一切正常。
但是在显示打印预览后,我现在需要打印,单击生成的预览上的打印图标会抛出臭名昭著的“调用线程无法访问此对象,因为其他线程拥有它。”异常(exception)。那么,有没有什么办法呢?
编辑(代码):
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 元素,该元素实际保存和显示预览,并包含打印图标,单击该图标后我会获得 PrintDialog 窗口。
编辑(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>`
最佳答案
最简单的方法是。
Action a = () =>
{
//Code from another thread.
};
Dispatcher.BeginInvoke(a);
关于wpf - 如何从 Dispatcher 线程访问单独的线程生成的 WPF UI 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11358647/