【问题标题】:How do you Bulk Print multiple Visual elements as one task?您如何将多个视觉元素作为一项任务批量打印?
【发布时间】:2013-07-04 13:39:00
【问题描述】:

我有多个UserControl,每个代表一个页面,但我不知道如何打印它们,因为到目前为止我只能打印一个UserControl

这是我打印单个 UserControl 的方法:

PrintDialog printDlg = new PrintDialog();
if (printDlg.ShowDialog() == true)
{
     printDlg.PrintVisual((UserControl)myUserControl, "optionalname");
}

如何在一项任务中打印来自 Visual 类型的多个对象?

【问题讨论】:

  • 只是一个想法。你能把所有视觉效果放在一个paren控件(即网格)中并打印那个控件吗?
  • @keftmedei 但我会得到 1 个页面,其中包含所有 UserControls 作为结果,而不是每个UserControl 1 个页面

标签: c# wpf object printing


【解决方案1】:

经过更多研究,我发现有人在关注Blog,但没有运气,因为他有一些复制和过去的错别字。我改正了他的错别字,效果很好。

这里是一个工作示例:

using System;
using System.Printing;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Windows.Media;
using System.Windows.Xps;

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        List<UIElement> UC = new List<UIElement>();

        for (int i = 0; i < 3; i++)
        {
            var uc = new UserControl
            {
                Background = Brushes.Red,
                Content = new TextBlock
                {
                    Text = "Box:" + i,
                    Margin = new Thickness(12),
                    Background = Brushes.Orange
                }
            };
            UC.Add(uc);
        }

        var pDialog = new PrintDialog();

        if (pDialog.ShowDialog() == true)
        {
            var xpsDocWriter = PrintQueue.CreateXpsDocumentWriter(pDialog.PrintQueue);
            PrintUIElements(xpsDocWriter, UC);
        }
    }

    /// <summary>
    /// Used the XpsDocumentWriter to write a FixedDocumentSequence which contains the UIElements as single pages
    /// </summary>
    /// <param name="xpsWriter"></param>
    /// <param name="uiElements"></param>
    private void PrintUIElements(XpsDocumentWriter xpsWriter, List<UIElement> uiElements)
    {
        FixedDocumentSequence fixedDocSeq = new FixedDocumentSequence();

        foreach (UIElement element in uiElements)
        {
            (fixedDocSeq as IAddChild).AddChild(toDocumentReference(element));

        }

        // write the FixedDocumentSequence as an XPS Document
        xpsWriter.Write(fixedDocSeq);
    }

    /// <summary>
    /// encapsulater for a UIElement in an DocumentReference
    /// DocumentReference(FixedDocument(PageContent(FixedPage(UIElement))))
    /// to simplify the print of multiple pages
    /// </summary>
    /// <param name="uiElement">the UIElement which</param>
    /// <returns>creates a DocumentReference</returns>
    private DocumentReference toDocumentReference(UIElement uiElement)
    {
        if (uiElement == null)
            throw new NullReferenceException("the UIElement has to be not null");

        FixedPage fixedPage = new FixedPage();
        PageContent pageContent = new PageContent();
        FixedDocument fixedDoc = new FixedDocument();
        DocumentReference docRef = new DocumentReference();

        #region Step1

        // add the UIElement object the FixedPage
        fixedPage.Children.Add(uiElement);

        #endregion

        #region Step2

        // add the FixedPage to the PageContent collection
        pageContent.BeginInit();
        ((IAddChild)pageContent).AddChild(fixedPage);
        pageContent.EndInit();

        #endregion

        #region Step 3

        // add the PageContent to the FixedDocument collection
        ((IAddChild)fixedDoc).AddChild(pageContent);

        #endregion

        #region Step 4

        // add the FixedDocument to the document reference collection
        docRef.BeginInit();
        docRef.SetDocument(fixedDoc);
        docRef.EndInit();

        #endregion

        return docRef;
    }
}

编辑

上面的代码包含第一页的绑定错误,但我能够修复它。

/// <summary>
/// Used the XpsDocumentWriter to write a FixedDocument which get created and contains the UIElements as single pages
/// </summary>
/// <param name="xpsWriter">XpsDocumentWriter</param>
/// <param name="uiElements">List of UIElement</param>
private void PrintUIElements(XpsDocumentWriter xpsWriter, List<UIElement> uiElements)
{
    var fixedDoc = new FixedDocument();

    foreach (UIElement element in uiElements)
    {
        var fixedPage = new FixedPage();
        var pageContent = new PageContent();

        // add the UIElement object the FixedPage
        fixedPage.Children.Add(element);

        // add the FixedPage object the PageContent
        pageContent.Child = fixedPage;

        // add the PageContent object the FixedDocument
        fixedDoc.Pages.Add(pageContent);
    }

    xpsWriter.Write(fixedDoc);
}

【讨论】:

  • 帖子中的博客链接已失效。博客已移至此处:ipushrocks.wordpress.com/2009/08/31/…
  • 您需要使用 .NET 4 或更高版本进行构建,就像您使用 .NET 3.5 一样,构建会失败,因为 pageContent.Child 是只读的。
猜你喜欢
  • 2010-09-05
  • 1970-01-01
  • 1970-01-01
  • 2018-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-23
  • 1970-01-01
相关资源
最近更新 更多