Sunday, October 24, 2010

WPF DocumentViewer

The WPF DocumentViewer control has some annoying features.

1. A find control ("Type text to find") that doesn't work.
2. A print function with limited configuration.

I work around these features by subclassing the DocumentViewer as follows:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows;
using System.Printing;
using System.Windows.Xps;

namespace FixedDocPrinting
{
public class PrintDocumentViewer : DocumentViewer
{
PageOrientation _pageOrientation = PageOrientation.Portrait;
public PageOrientation PageOrientation
{
get { return _pageOrientation; }
set { _pageOrientation = value; }
}

Visibility _findControlVisibility = Visibility.Collapsed;
public Visibility FindControlVisibility
{
get
{
return _findControlVisibility;
}
set
{
_findControlVisibility = value;
UpdateFindControlVisibility();
}
}

private void UpdateFindControlVisibility()
{
object toolbar = this.Template.FindName("PART_FindToolBarHost", this);
ContentControl cc = toolbar as ContentControl;
if (cc != null)
{
HeaderedItemsControl itemsControl = cc.Content as HeaderedItemsControl;
if (itemsControl != null)
itemsControl.Visibility = FindControlVisibility;
}
}

public PrintDocumentViewer()
{
Loaded += new RoutedEventHandler(PrintDocumentViewer_Loaded);
}

void PrintDocumentViewer_Loaded(object sender, RoutedEventArgs e)
{
UpdateFindControlVisibility();
}

protected override void OnPrintCommand()
{
PrintDialog printDialog = new PrintDialog();
printDialog.PrintQueue = LocalPrintServer.GetDefaultPrintQueue();
printDialog.PrintTicket = printDialog.PrintQueue.DefaultPrintTicket;

printDialog.PrintTicket.PageOrientation = PageOrientation;

if (printDialog.ShowDialog() == true)
{
// Code assumes this.Document will either by a FixedDocument or a FixedDocumentSequence
FixedDocument fixedDocument = this.Document as FixedDocument;
FixedDocumentSequence fixedDocumentSequence = this.Document as FixedDocumentSequence;

if (fixedDocument != null)
fixedDocument.PrintTicket = printDialog.PrintTicket;

if (fixedDocumentSequence!= null)
fixedDocumentSequence.PrintTicket = printDialog.PrintTicket;

XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(printDialog.PrintQueue);

if (fixedDocument != null)
writer.WriteAsync(fixedDocument, printDialog.PrintTicket);

if (fixedDocumentSequence != null)
writer.WriteAsync(fixedDocumentSequence, printDialog.PrintTicket);
}
}
}
}

This hides the find control and gives me the ability to print in Landscape.

To use this code, you will need to add a reference to the ReachFramework dll which contains useful classes in the System.Printing and System.Windows.Xps name spaces.


No comments:

Post a Comment