Using the WPF DocumentViewer

The most appropriate technology to embed documents and reports in a WPF application is undoubtedly XPS. XPS stands for XML Paper Specification and includes a number of technologies for rendering, publishing, and printing documents. Creating a report is pretty simple: all you need to do is create an XPS file. This is a file with a '.xps'-extension. It's actually a zip file (a.k.a. the Package) that contains binary and XML files (a.k.a. the Parts). An XPS document must contain at least one fixed payload, starting with FixedDocumentSequence. WPF developers will certainly appreciate the fact that the XPS format is closely related to XAML.

The .NET Framework (3.x) ships with the DocumentViewer control for displaying XPS documents in WPF applications. Embed one in a Window, Page, or UserControl, and set its Document property to refer to either a FixedDocument or a FixedDocumentSequence. The DocumentViewer will render the document and provide navigation, zoom, print, and search controls.

Here's the source for a small demo, I hope the comments speak for themselves:

XAML

<Window x:Class="DockOfTheBay.XpsSample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="XPS Report Sample" Height="300" Width="300">
        <DocumentViewer Name="documentViewer1" />
</Window>

C#

namespace DockOfTheBay
{
    using System;
    using System.IO;
    using System.Windows;
    using System.Windows.Markup;
    using System.Windows.Media;
    using System.Windows.Shapes;
    using System.Windows.Xps.Packaging;
    using System.Xml;
 
    public partial class XpsSample : Window
    {
        public XpsSample()
        {
            InitializeComponent();
 
            ////
            // 1. Generate
            ////
 
            // Create temporary file
            string tempFileName = System.IO.Path.GetTempPath();
            tempFileName = System.IO.Path.Combine(tempFileName, Guid.NewGuid().ToString() + ".xps");
 
            // Create XPS Document
            XpsDocument document = new XpsDocument(tempFileName, FileAccess.ReadWrite);
 
            // Create FixedDocumentSequence object in document
            IXpsFixedDocumentSequenceWriter docSeqWriter = document.AddFixedDocumentSequence();
 
            // Create FixedDocument in document sequence 
            IXpsFixedDocumentWriter docWriter = docSeqWriter.AddFixedDocument();
 
            // Create FixedPage in fixedDocument
            IXpsFixedPageWriter pageWriter = docWriter.AddFixedPage();
 
            // Get XML Writer and start page
            XmlWriter xmlWriter = pageWriter.XmlWriter;
            xmlWriter.WriteStartElement("FixedPage");
            xmlWriter.WriteAttributeString("xmlns", "http://schemas.microsoft.com/xps/2005/06");
            xmlWriter.WriteStartElement("StackPanel");
            xmlWriter.WriteAttributeString("Margin", "20");
 
            // Write some XML into the page
            // (the masochistic way)
            xmlWriter.WriteStartElement("TextBlock");
            xmlWriter.WriteString("Dock of the Bay");
            xmlWriter.WriteEndElement(); // TextBlock
 
            // Write some XML into the page
            // (the more developer friendly way) 
            Ellipse e = new Ellipse();
            e.Height = 50;
            e.Width = 50;
            e.Fill = Brushes.LightBlue;
            e.Stroke = Brushes.Gray;
            e.StrokeThickness = 2;
            e.ToolTip = "Wow";
            e.Margin = new Thickness(0, 20, 0, 0);
            XamlWriter.Save(e, xmlWriter);
 
            xmlWriter.WriteEndElement(); // StackPanel
            xmlWriter.WriteEndElement(); // FixedPage
 
            // Save page content to package
            pageWriter.Commit();
 
            docWriter.Commit();
 
            docSeqWriter.Commit();
 
            ////
            // 2. Display
            ////
 
            documentViewer1.Document = document.GetFixedDocumentSequence();
 
            // Close XPS
            document.Close();
 
            // Delete temporary file
            File.Delete(tempFileName);
        }
    }
}

Here's what the result looks like:

3 comments:

  1. the xps file generated open in documentviewer, but not in xpsviewer nor in browser...

    ReplyDelete
  2. Thank you for effort , it is very helpful

    ReplyDelete