我在尝试打印存储在.xaml文件中的FlowDocument
时发现了一种奇怪的行为。让我告诉你这是如何工作的。我们有一个简单的类似ViewModel的类:
public class FooViewModel
{
public FlowDocument Fd { get; set; }
public FooViewModel()
{
this.Fd = Application.LoadComponent(new Uri("/someassembly;component/somepath.xaml", UriKind.Relative)) as FlowDocument;
}
public void Print()
{
PrintDialog pd new PrintDialog();
pd.PrintQueue = new PrintQueue(new LocalPrintServer(), "Canon MP280 series");
FlowDocument document = this.Fd;
document.DataContext = new LabelTicket(); //stores data for printing
DocumentPaginator dp = ((IDocumentPaginatorSource)document).DocumentPaginator;
pd.PrintDocument(dp, "someTitle");
}
}
此代码有效,打印作业已开始,物理打印机正在执行此操作。但是当我们将Print()
方法中的一行更改为:
FlowDocument document = Application.LoadComponent(new Uri("/someassembly;component/somepath.xaml", UriKind.Relative)) as FlowDocument;
奇怪的事情开始发生。将组件加载延迟到实际打印使得不可能进行打印。打印作业出现在此特定打印机的Windows打印队列中,但几乎立即消失。打开Windows事件跟踪进行打印显示:"打印处理器返回的Win32错误代码:63(0x3f)。"将打印机更改为任何其他物理打印机可以产生相同的效果。
另一方面,将打印机更换为任何非物理打印机,例如" Microsoft XPS Document Writer"毫无问题地执行此打印。
我还尝试从ResourceDictionary加载FlowDocument
,但效果相同。有人能给我一个如何解决这个问题的提示吗?
答案 0 :(得分:0)
不那么明显的答案可能是你需要“显示”FlowDocument
,以便它知道如何以某种方式呈现。使用像XPS Doc Writer这样的虚拟打印机,它可能知道如何正确呈现FlowDocument
。在没有安装XPS驱动程序的打印机上,它可能不知道如何正确呈现。
您最好的选择可能是“静默”渲染FlowDocument
,然后再将其发送到打印机。此外,这可能不是纯MVVM视图模型,因为您的视图模型可能不应该引用FlowDocument
甚至PrintDialog
。
无论如何,你可以尝试做这样的事情来静默渲染:
public void Print()
{
PrintDialog pd = new PrintDialog();
if(pd.ShowDialog() == true) //allow user to pick printer and preferences if they choose to do so
{
FlowDocument document = Application.LoadComponent(new Uri("/someassembly;component/somepath.xaml", UriKind.Relative)) as FlowDocument;
document.DataContext = new LabelTicket(); //stores data for printing
Grid g = new Grid();
ContentPresenter cp = new ContentPresenter();
cp.Content = document;
g.Children.Add(cp);
var _printableAreaSize = new Size(pd.PrintableAreaWidth, pd.PrintableAreaHeight);
g.Measure(_printableAreaSize);
g.Arrange(new Rect(new Point(), _printableAreaSize));
g.UpdateLayout();
DocumentPaginator dp = ((IDocumentPaginatorSource)document).DocumentPaginator;
pd.PrintDocument(dp, "someTitle");
}
}
当您逐步执行Measure / Arrange / UpdateLayout调用时,您应该会看到Grid
的高度/宽度发生变化,因为它正在渲染而未实际显示。