IntroductionOften we need to print the screen or some parts of the screen. This is pretty useful for printing graphic reports, like charts. In this article, we’re going to have a look at how to print a visual element with the WPF Visual Print. The essential part is serializing an XAML element to an XPS document, and converting the XPS document to a FlowDocument. Then we print and print preview the FlowDocument with the FlowDocument Viewer. What is an XPS DocumentThe XML Paper Specification (XPS) format is basically an electronic representation of digital documents based on XML. It is a paginated fixed-layout format that retains the look and feel of your electronic documents. XPS documents can be easily created once you have the right software installed, like Microsoft Word. The parts of an XPS document are organized in a logical hierarchy with the FixedDocumentSequence part at the top. An XPS document package may contain more than one document, and the sequence of these documents is described by the FixedDocumentSequence part. The FixedDocumentSequence part references the FixedDocument parts that, in turn, reference the pages of each document within the package. Each FixedDocument part references the pages of that document as FixedPage parts. Each FixedPage part contains the text markup and layout of a page in the document as well as references to images, fonts, and other custom resources used in the page. Resources such as images and fonts are stored in the package but outside of the FixedPage part, allowing them to be shared by other pages. This is especially useful for font resources, but it could also be useful for any image resource that is used on more than one page, such as a watermark or letterhead logo. I know it’s pretty boring for you to read these definitions. But I have to bring them out, because all these definitions will be used in the WPF Visual Print code.Serialize a Visual Component to XPS Document XPS documents are stored in a file, called a package, that conforms to the Open Packaging Conventions and are composed of a set of document components known as parts. A package has a physical and a logical organization. The physical organization consists of the document parts and folders inside the package, and the logical organization is a hierarchy described by the document parts. The XML Paper Specification applies a specific organization and naming convention to the logical layer for XPS documents. WPF wraps the XPS API in the XPSSerializationManager class. Thus WPF can create an XPS document by serializing the XAML element page to an XPS document. Here is our serialization code:FrameworkElement fe = (visual as FrameworkElement);
fe.Measure(new Size(Int32.MaxValue, Int32.MaxValue));
Size visualSize = fe.DesiredSize;
fe.Arrange(new Rect(new Point(0, 0), visualSize));
MemoryStream stream = new MemoryStream();
string pack = "pack://temp.xps";
Uri uri = new Uri(pack);
DocumentPaginator paginator;
XpsDocument xpsDoc;using (Package container = Package.Open(stream, FileMode.Create))
{
PackageStore.AddPackage(uri, container);
using (xpsDoc = new XpsDocument(container, CompressionOption.Fast, pack))
{
XpsSerializationManager rsm =
new XpsSerializationManager(new XpsPackagingPolicy(xpsDoc), false);
rsm.SaveAsXaml(visual);
paginator = ((IDocumentPaginatorSource)
xpsDoc.GetFixedDocumentSequence()).DocumentPaginator;
paginator.PageSize = visualSize;
}
PackageStore.RemovePackage(uri);
}Custom Document PaginatorWhen you serialize a XAML element to an XPS document, it’s always one page. Apparently, it’s not good enough for visual elements that need multiple pages. So you need to write your own paginator class, VisualDocumentPaginator. Read more: Codeproject
fe.Measure(new Size(Int32.MaxValue, Int32.MaxValue));
Size visualSize = fe.DesiredSize;
fe.Arrange(new Rect(new Point(0, 0), visualSize));
MemoryStream stream = new MemoryStream();
string pack = "pack://temp.xps";
Uri uri = new Uri(pack);
DocumentPaginator paginator;
XpsDocument xpsDoc;using (Package container = Package.Open(stream, FileMode.Create))
{
PackageStore.AddPackage(uri, container);
using (xpsDoc = new XpsDocument(container, CompressionOption.Fast, pack))
{
XpsSerializationManager rsm =
new XpsSerializationManager(new XpsPackagingPolicy(xpsDoc), false);
rsm.SaveAsXaml(visual);
paginator = ((IDocumentPaginatorSource)
xpsDoc.GetFixedDocumentSequence()).DocumentPaginator;
paginator.PageSize = visualSize;
}
PackageStore.RemovePackage(uri);
}Custom Document PaginatorWhen you serialize a XAML element to an XPS document, it’s always one page. Apparently, it’s not good enough for visual elements that need multiple pages. So you need to write your own paginator class, VisualDocumentPaginator. Read more: Codeproject
1 comments:
It's a pity you don't have a donate button!
I'd certainly donate to this excellent blog! I guess for now i'll
settle for book-marking and adding your RSS feed to my Google account.
I look forward to new updates and will share this website with
my Facebook group. Talk soon!
Here is my weblog; waist to height ratio calculator
Post a Comment