XPS viewing in three lines

I was involved in a conversation this week where someone mentioned "it's just 2 lines of code", So I thought I'd go one line better and provide an example of how to leverage WPF and Visual Studio to do an XPS Viewer in 3 lines of code.

To get yourself setup, you'll need to be running Visual Studio (I happened to use the Express Edition) with the extensions for .NET Framework 3.0. I'm also assuming that you're running on Windows Vista, otherwise you'll also need the .NET Framework 3.0.

That done, here we go...

One line of XAML

    1: <DocumentViewer Name="documentViewer"/>

and two lines of C#

    1: XpsDocument xpsDoc = new XpsDocument(fileName, System.IO.FileAccess.Read); 
    2: documentViewer.Document = xpsDoc.GetFixedDocumentSequence(); 

Is that it? Well, kinda...

The first line (XAML) creates an instance of a DocumentViewer class. DocumentViewer can host paginated FixedDocument content, and that includes XPS content since XPS is a format for storing paginated fixed layout content.

The second (C#) creates a new XPSDocument object and initializes it with the path to an XPS file on disk with a read only flag. Note that this constructor for XPSDocument keeps the XPS package open as a performance optimization so you'd want to call the close() method when done (okay — let's compromise and say 3.5 lines ;-).

The third line (C#) sets the Document property of the DocumentViewer to the FixedDocumentSequence provided by the XPSDocument object and that's it — you have a complete XPS viewer running within your application with toolbars, search & context menu! 

myXPSViewer

Now to be honest, I find the default UI of the DocumentViewer a little cluttered, it's not that I'm minimalist, but when I'm reading I like the screen to be used for the content I'm reading, and not displaying loads of other stuff. Fortunately, DocumentViewer supports styling so I can do something like the following to remove some elements I consider extraneous.

First, define a simple style using XAML:

    1: <Style x:Key="plainStyleKey" TargetType="{x:Type DocumentViewer}"> 
    2:   <Setter Property="Template"> 
    3:     <Setter.Value> 
    4:       <ControlTemplate TargetType="{x:Type DocumentViewer}"> 
    5:         <ScrollViewer CanContentScroll="True" Focusable="True" 
    6:            HorizontalScrollBarVisibility="Auto" 
    7:            VerticalScrollBarVisibility="Auto" 
    8:            x:Name="PART_ContentHost" /> 
    9:       </ControlTemplate> 
   10:     </Setter.Value> 
   11:   </Setter> 
   12: </Style> 
   13:  

 

and then add some code behind to select the style:

    1: documentViewer.Style = FindResource("plainStyleKey") as Style;

 

DocumentViewer is a flexible component, it exposes a load of functionality that you can use to automate the display and navigation of XPS content.

 

If DocumentViewer looks interesting, check out the documentation and samples on MSDN. If you want to go to the other extreme, a good place to start is a simple XPS decoder in unmanaged C++ described in this post from Feng.