使用预览在纸质表单上打印

时间:2013-03-13 15:32:16

标签: c# wpf mvvm printing

我们需要填写大量纸质表格。手动执行此操作非常繁琐,因此我们正在构建应用程序。它应该提供一个表格来填写数据,能够显示打印预览,在纸质表格上打印数据,并保留历史记录。

目前,我们有一个FixedPage,我们这样打印:

var dlg = new PrintDialog();
if (dlg.ShowDialog() == true)
{
    var doc = new FixedDocument();
    doc.DocumentPaginator.PageSize = new Size(11.69 * 96, 8.27 * 96); // A4 Landscape

    var fp = Application.LoadComponent(new Uri("/FixedPage.xaml", UriKind.Relative)) as FixedPage;
    fp.DataContext = this;
    fp.UpdateLayout();

    var pc = new PageContent();
    ((IAddChild)pc).AddChild(fp);
    doc.Pages.Add(pc);

    dlg.PrintTicket.PageOrientation = System.Printing.PageOrientation.Landscape;
    dlg.PrintDocument(doc.DocumentPaginator, string.Format("Form #{0}", FormNumber));
}

对于打印预览,我们有一个自定义UserControl,其中包含背景纸张形式的扫描图像和前景数据。基本上,它正在重复FixedPage布局,这一切使我们认为我们的设计存在缺陷。

有没有更好的方法来做我们想要的事情?

2 个答案:

答案 0 :(得分:2)

我的任务是同样的问题,并希望避免编写自己的模板系统来节省时间,单元测试和我的理智。

我最后写了一个混合物来做一些很酷的事情。首先,我使用HTML和CSS编写模板。这很容易做到,并且在我们的营销部门进行微调时可以提供很大的灵活性。

我用自己的标签填充模板(例如[code_type /],[day_list] ... [/ day_list]),字符串将文本替换为可以是单个或多值的标签字典。

生成html后,我会使用html to pdf库,我发现它使用开源webkit引擎来渲染和创建生成的pdf。结果非常稳定,花了大约2周时间编写初始程序。每个人都非常高兴,测试也很轻松。

如果您想了解更多详情,请给我发消息或回复。

答案 1 :(得分:1)

我们设法找到了一个解决方案,它允许我们丢弃一堆冗余代码。它仍然很难看:

public class CustomDocumentViewer : DocumentViewer
{
    public static readonly DependencyProperty BackgroundImageProperty =
        DependencyProperty.Register("BackgroundImage", typeof(Image), typeof(CustomDocumentViewer), new UIPropertyMetadata(null));

    public Image BackgroundImage
    {
        get { return GetValue(BackgroundImageProperty) as Image; }
        set { SetValue(BackgroundImageProperty, value); }
    }

    protected override void OnDocumentChanged()
    {
        (Document as FixedDocument).Pages[0].Child.Children.Insert(0, BackgroundImage);
        base.OnDocumentChanged();
    }

    protected override void OnPrintCommand()
    {
        var printDialog = new PrintDialog();
        if (printDialog.ShowDialog() == true)
        {
            (Document as FixedDocument).Pages[0].Child.Children.RemoveAt(0);
            printDialog.PrintDocument(Document.DocumentPaginator, "Test page");
            (Document as FixedDocument).Pages[0].Child.Children.Insert(0, BackgroundImage);
        }
    }
}

...

<local:CustomDocumentViewer x:Name="viewer" BackgroundImage="{StaticResource PaperFormImage}"/>

...

InitializeComponent();
viewer.Document = Application.LoadComponent(new Uri("/PaperFormDocument.xaml", UriKind.Relative)) as IDocumentPaginatorSource;

我们使用Application.LoadComponent而不是绑定的原因是一个五年前的错误:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=293646