Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 带预览的纸质表单打印_C#_Wpf_Mvvm_Printing - Fatal编程技术网

C# 带预览的纸质表单打印

C# 带预览的纸质表单打印,c#,wpf,mvvm,printing,C#,Wpf,Mvvm,Printing,我们有大量的纸质表格需要填写。手工操作非常繁琐,因此我们正在构建一个应用程序。它应该提供一个表单来填写数据,能够显示打印预览,在纸质表单上打印数据,并保留历史记录 目前,我们有一个FixedPage,打印方式如下: var dlg = new PrintDialog(); if (dlg.ShowDialog() == true) { var doc = new FixedDocument(); doc.DocumentPaginator.PageSize = new Size(

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

目前,我们有一个
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
布局,所有这些都让我们认为我们的设计存在缺陷


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

我也面临同样的问题,希望避免编写自己的模板系统来节省时间、单元测试和理智

最后我写了一个混合体来做一些很酷的事情。首先,我使用HTML和CSS编写模板。这是非常容易做到的,并允许很大的灵活性时,作出轻微的调整,从我们的营销部门

我用自己的标记(例如[code_type/]、[day_list]…[/day_list])填充模板,并用一个标签字典(可以是单值或多值标签)替换文本

生成html后,我将使用我发现的html到pdf库,该库使用开源webkit引擎来呈现和创建生成的pdf。结果证明它非常稳定,并且花了大约2周的时间编写初始程序。大家都很高兴,测试轻而易举


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

我们已经找到了一个解决方案,它允许我们扔掉一堆renundant代码。它仍然丑陋:

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;
公共类CustomDocumentViewer:DocumentViewer { 公共静态只读从属属性BackgroundImageProperty= DependencyProperty.Register(“BackgroundImage”、typeof(Image)、typeof(CustomDocumentViewer)、new UIPropertyMetadata(null)); 公众形象背景形象 { 获取{返回GetValue(BackgroundImageProperty)作为图像;} set{SetValue(BackgroundImageProperty,value);} } 受保护的覆盖无效OnDocumentChanged() { (文档作为固定文档)。页面[0]。Child.Children.Insert(0,背景图像); base.OnDocumentChanged(); } 受保护的覆盖无效OnPrintCommand() { var printDialog=新建printDialog(); if(printDialog.ShowDialog()==true) { (作为固定文档的文档)。页面[0]。Child.Children.RemoveAt(0); printDialog.PrintDocument(Document.DocumentPaginator,“测试页”); (文档作为固定文档)。页面[0]。Child.Children.Insert(0,背景图像); } } } ... ... 初始化组件(); viewer.Document=Application.LoadComponent(新Uri(“/PaperFormDocument.xaml”,UriKind.Relative))作为IDocumentPaginatorSource;
我们使用
Application.LoadComponent
而不是绑定的原因是一个五年前的错误:

我认为您可以从中受益,我认为最好的方法是使用它进行打印和预览。我自己从来没用过打印对话框。但应该有打印预览而不是纸张。这可能只是另一个设备或类似的东西。@Dzyann,谢谢,看起来不错!但是,我不太确定在预览中如何显示背景图像,而不将其打印在纸上。如果你提供一个例子,我很乐意接受它作为一个答案。你用于布局的用户控件是否可能只包含一个画布,背景是扫描的图像,在cambas中你直接使用FixedPage.xmal?@Dzyann,可能会,但这就是现在的情况:两个控件,这在一个图像上是不同的。我希望避免这种情况,并构建一个预览窗口(我想像.NET这样的框架必须准备好一个)。如何显示打印预览?我想我仍然需要两个不同的模板-一个有背景图像(用于预览),一个没有(用于打印)。我没有。我刚刚在视图中呈现了html。:)