web-dev-qa-db-ja.com

WPF FlowDocumentの印刷

私はWPFでデモアプリを構築していますが、これは私にとって初めてのことです。現在、FlowDocumentにテキストを表示していますが、印刷する必要があります。

私が使用しているコードは次のようになります。

        PrintDialog pd = new PrintDialog();
        fd.PageHeight = pd.PrintableAreaHeight;
        fd.PageWidth = pd.PrintableAreaWidth;
        fd.PagePadding = new Thickness(50);
        fd.ColumnGap = 0;
        fd.ColumnWidth = pd.PrintableAreaWidth;

        IDocumentPaginatorSource dps = fd;
        pd.PrintDocument(dps.DocumentPaginator, "flow doc");

fdはFlowDocumentであり、今のところ、ユーザーが印刷オプションを指定できるようにする代わりに、デフォルトのプリンターを使用しています。ドキュメントが印刷された後、画面に表示されるFlowDocumentが、印刷用に指定した設定を使用するように変更されたことを除いて、正常に機能します。

印刷後にすべてを手動でリセットすることでこれを修正できますが、これが最良の方法ですか?印刷する前にFlowDocumentのコピーを作成する必要がありますか?または、考慮すべき別のアプローチがありますか?

33
Jason

はい、印刷する前にFlowDocumentのコピーを作成します。これは、ページネーションとマージンが異なるためです。これは私のために働く。

    private void DoThePrint(System.Windows.Documents.FlowDocument document)
    {
        // Clone the source document's content into a new FlowDocument.
        // This is because the pagination for the printer needs to be
        // done differently than the pagination for the displayed page.
        // We print the copy, rather that the original FlowDocument.
        System.IO.MemoryStream s = new System.IO.MemoryStream();
        TextRange source = new TextRange(document.ContentStart, document.ContentEnd);
        source.Save(s, DataFormats.Xaml);
        FlowDocument copy = new FlowDocument();
        TextRange dest = new TextRange(copy.ContentStart, copy.ContentEnd);
        dest.Load(s, DataFormats.Xaml);

        // Create a XpsDocumentWriter object, implicitly opening a Windows common print dialog,
        // and allowing the user to select a printer.

        // get information about the dimensions of the seleted printer+media.
        System.Printing.PrintDocumentImageableArea ia = null;
        System.Windows.Xps.XpsDocumentWriter docWriter = System.Printing.PrintQueue.CreateXpsDocumentWriter(ref ia);

        if (docWriter != null && ia != null)
        {
            DocumentPaginator paginator = ((IDocumentPaginatorSource)copy).DocumentPaginator;

            // Change the PageSize and PagePadding for the document to match the CanvasSize for the printer device.
            paginator.PageSize = new Size(ia.MediaSizeWidth, ia.MediaSizeHeight);
            Thickness t = new Thickness(72);  // copy.PagePadding;
            copy.PagePadding = new Thickness(
                             Math.Max(ia.OriginWidth, t.Left),
                               Math.Max(ia.OriginHeight, t.Top),
                               Math.Max(ia.MediaSizeWidth - (ia.OriginWidth + ia.ExtentWidth), t.Right),
                               Math.Max(ia.MediaSizeHeight - (ia.OriginHeight + ia.ExtentHeight), t.Bottom));

            copy.ColumnWidth = double.PositiveInfinity;
            //copy.PageWidth = 528; // allow the page to be the natural with of the output device

            // Send content to the printer.
            docWriter.Write(paginator);
        }

    }
38
Cheeso

以下のURLのコードを使用できます。フロードキュメントを固定ドキュメントにラップして印刷します。大きな利点は、それを使用してマージン、ヘッダー、フッターを追加できることです。

http://blogs.msdn.com/fyuan/archive/2007/03/10/convert-xaml-flow-document-to-xps-with-style-multiple-page-page-size-header- margin.aspx

7
Nir

以下は、テキストビジュアルと非テキストビジュアルの両方で機能します:

//Clone the source document
var str = XamlWriter.Save(FlowDoc);
var stringReader = new System.IO.StringReader(str);
var xmlReader = XmlReader.Create(stringReader);
var CloneDoc = XamlReader.Load(xmlReader) as FlowDocument;

//Now print using PrintDialog
var pd = new PrintDialog();

if (pd.ShowDialog().Value)
{
  CloneDoc.PageHeight = pd.PrintableAreaHeight;
  CloneDoc.PageWidth = pd.PrintableAreaWidth;
  IDocumentPaginatorSource idocument = CloneDoc as IDocumentPaginatorSource;

  pd.PrintDocument(idocument.DocumentPaginator, "Printing FlowDocument");
}
2
dotNET

フロードキュメントからWPFレポートも生成していますが、フロードキュメントを印刷プレビュー画面として意図的に使用しています。余白を同じにしたいのです。 ここでこれをどのように行ったか について読むことができます。

あなたのシナリオでは、フロードキュメント全体ではなく、設定のコピーを作成しない理由を考えています。ドキュメントを元の状態に戻す場合は、設定を再適用できます。

0
Allan