【问题标题】:Printing a Collection in WPF在 WPF 中打印集合
【发布时间】:2010-09-17 08:01:19
【问题描述】:

有没有办法在内存集合中打印或在 WPF 中可变大小?

我正在使用以下代码打印 ListView 控件。但是当内容大于垂直滚动条时会接管并剪切内容。

 PrintDialog printDialog = new PrintDialog();
                printDialog.ShowDialog();

                printDialog.PrintVisual(lvDocumentSummary, "testing printing!");

【问题讨论】:

    标签: wpf printing printdialog


    【解决方案1】:

    要打印多个页面,您只需要使用一个实现 DocumentPaginator 的类 FixedDocument 是更复杂的实现之一,FlowDocument 是一个更简单的实现。

    FlowDocument fd = new FlowDocument();
    
    foreach(object item in items)
    {
        fd.Blocks.Add(new Paragraph(new Run(item.ToString())));
    }
    
    fd.Print();
    

    PrintDialog pd = new PrintDialog();
    pd.PrintDocument(fd);
    

    【讨论】:

    • 这不起作用。无法将 FlowDocument 转换为 DocumentPaginator。 FlowDocument 也没有 Print() 方法
    【解决方案2】:

    FixedDocument 像任何其他 xaml 文档一样支持 DataBinding(FlowDocument 除外)。只需将列表视图托管在固定文档中并将其显示在 DocumentViewer(具有内置打印支持)中。

    但是,如果您的列表对于一页来说太长,FixedDocument 不会自动生成新页面(就像 flowdocument 那样)。因此,您必须使用代码手动创建一个新页面,因为这不能在纯 xaml 中完成。

    【讨论】:

      【解决方案3】:

      如果您想从 WPF 进行良好的打印,您需要构建一个 FixedDocument 并打印它,不幸的是它可能非常复杂,具体取决于您要打印的内容。

      这里有一些创建 FixedDocument 的示例代码:http://www.ericsink.com/wpf3d/B_Printing.html

      【讨论】:

        【解决方案4】:

        这是 2019 年的答案。一些旧的答案不再起作用,例如。 FlowDocumentReader 没有Print 方法。

                private void Button_Click(object sender, RoutedEventArgs e)
                {
                    FlowDocument fd = new FlowDocument();
                    foreach (var item in COLLECTION) //<- put your collection here
                    {
                        fd.Blocks.Add(new Paragraph(new Run(item.ToString())));
                    }
        
                    PrintDialog pd = new PrintDialog();
                    if (pd.ShowDialog() != true) return;
        
                    fd.PageHeight = pd.PrintableAreaHeight;
                    fd.PageWidth = pd.PrintableAreaWidth;
        
                    IDocumentPaginatorSource idocument = fd as IDocumentPaginatorSource;
        
                    pd.PrintDocument(idocument.DocumentPaginator, "Printing Flow Document...");
                }
            }
        

        【讨论】:

          【解决方案5】:

          有趣,ListView 是虚拟化的吗?如果是,则未绘制对象,这是一种可能性。看看 Petzold 的印刷example

          【讨论】:

          • 我已经查看了该示例,但他正在使用文件进行打印。我有一个内存集合要打印!
          • Petzold 链接不再存在
          【解决方案6】:

          这是我对这个问题的解决方案。这有点不稳定,但适用于我的场景。

          我阅读了我的收藏并将其转换为字符串。整个集合现在驻留在 StringBuilder 对象中。接下来,我在客户端机器上看到文本/字符串到一个文件中,然后使用 /p 运行记事本进程以打印文件的内容。

          它工作并成功打印内容。

          最后,有一个定时器在 5 秒后被调用并删除文件。基本上在 5 秒内请求已经发送到打印机队列。但更好的解决方案是确保以这种方式处理打印作业,您将 100% 确定作业已执行。

          【讨论】:

          • 外部应用程序调用打印东西,有竞争条件?没门!并认为您运行的是开发知识库网站!可怕的东西。
          • 您可以通过使用 FlowDocument 和 FixedDocuments 轻松实现此目的!
          • 这是一个非常糟糕的方法,你只有一个带有 BlockUIContainer 的 FlowDocument。如果列表特别长,请使用 FixedDocument。
          猜你喜欢
          • 1970-01-01
          • 2023-03-17
          • 2023-04-09
          • 2011-12-17
          • 2017-12-19
          • 1970-01-01
          • 1970-01-01
          • 2021-12-22
          相关资源
          最近更新 更多