更改一行代码时,将删除C#WPF打印作业

时间:2016-03-07 17:04:36

标签: c# wpf printing flowdocument

我在尝试打印存储在.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,但效果相同。有人能给我一个如何解决这个问题的提示吗?

1 个答案:

答案 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的高度/宽度发生变化,因为它正在渲染而未实际显示。