State Street Gang
.NET, straight up

New XAML goodness in 4.0?

October 30, 2008 11:35 by will

Was just scoping out the .NET 4.0 poster here when I zoomed in on core and saw...

CropperCapture[2]

Looks like there's movement on making XAML more available to developers for serializing plain old CLR objects.  Unfortunately, my Google-fu is failing me; I can't find any more information about what's happening here...


Tags:
Categories: XAML
Actions: E-mail | Permalink | Comments (1) | Comment RSSRSS comment feed

More on XAML Serialization

July 29, 2008 16:22 by will

I'm just finishing off the big refactor at work, moving from XML serialization to XAML serialization.  Part of the refactor covered some needed code changes that impacted serialization; specifically, I had to convert a pseudo-collection object into a true collection.  Everything worked fine, but when I tested serialization it failed on the deserialize side.  It took me a friggen day and a half to weed out what was going on (thanks, IAddChildInternal!).  I record it here so that the engineers at Microsoft can copy it into a Word doc and send it to people looking for some tech support (see the update at the bottom of that post, heh heh).

More...

Tags:
Categories: XAML
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

XAML Serialization FTW

June 23, 2008 07:19 by Will

Foreground

I wanted to record some of the things I learned recently about XAML serialization of generic dictionaries.  This subject is of interest to anybody who is interested in creating FrameworkElement objects that expose dictionary collections or those, like me, who are exploring the use of XAML serialization as an alternative for XML or other string-based serialization methods.

More...

Tags:
Categories: XAML
Actions: E-mail | Permalink | Comments (3) | Comment RSSRSS comment feed

Creating an XPS document in memory via the DOM

March 14, 2008 12:09 by Will

Most of the examples out there covering the creation of XPS documents use the file system as a backing store.  This isn't optimal; in a server situation its downright stupid.  So, how do you create an XPS document in memory?

I've created a sample project (VS 2005) with the code in this article.  Jump down to the bottom of the post to download it and follow along.

A word (or many) about Packages

XPS documents use the Open Packaging Conventions, which are a shared description of how content can be organized within a package.  A package, in this case, is a collection of other content types that can be addressed as a single object.  Content can be accessed within a package via URIs, loaded on demand rather than all at once.  An advantage of this can be seen when accessing a document over a network. 

Office 2007 documents adhere to these conventions.  For example, a word document contains not only the text of the document but the fonts, images, edit history, etc.  All of these parts are different, but they are combined together within the package to create the whole document.

XPS documents are the same.  The in-memory representation of an XPS document works closely with its Package to manage its content.  Packages, as mentioned before, are collections of parts. These parts may be local, or they may be located on another server.  Because of this, loading of package parts can be slow.  To speed up loading of package parts, the PackageStore is used to manage references to these parts and perform local caching. 

So, when creating XPS documents in memory, what we are actually doing is saving parts of the XPS document to a package managed by the PackageStore.  It is due to the flexibility and the power of the design that our job is a bit more complex than just new-ing up an XPS document and adding children to it.

Enough, how about some code?

The first steps to creating an XPS document in memory are to create an XpsDocument and a MemoryStream.  The XpsDocument object controls how parts are added to the package, and the package stores these parts in the MemoryStream.  Remember, the MemoryStream must be disposed when you are done with it, and you are done with it when you are done with the XPS document; either because you are discarding it or because you have written it to whatever backing store you are using (disk, database, etc).

XpsDocument doc;
ms = new MemoryStream(); 

Next, we open a Package on the MemoryStream.  We must tell the Package that we are creating a new document on this stream, and that we wish to be able to read and write to the document.  I wish these'd be called StreamMode and StreamAccess, but since streams came from the file system originally, these enums bear the marks of their heritage.  In addition, we create a PackageStore to manage our Package.  This uses a URI to reference our XPS document, so we create one using the "pack:" URI scheme, since the document is located in a local Package.  The same URI marks our XPS document

Package p = Package.Open(ms, FileMode.Create, FileAccess.ReadWrite);
Uri DocumentUri = new Uri("pack://document.xps");
PackageStore.AddPackage(DocumentUri, p);
doc = new XpsDocument(p, 
	CompressionOption.NotCompressed, 
	DocumentUri.AbsoluteUri);

Creating our DOM in memory is the next step.  Its pretty simple to understand, for the most part.

XPS documents contain one or more FixedDocuments within a "fixed document sequence," which is an ordered collection of individual FixedDocuments.  Each FixedDocument contains one or more pages, represented by PageContent objects.  Each PageContent can have one single child; since XPS documents are designed for fixed layouts, the most obvious type to use as a child is the FixedPage.  For some reason, you cannot add a FixedPage directly to a PageContent; you must first explicitly cast the content page as IAddChild.  I'm not sure exactly why this is.  If anybody has a clue, a comment would be nice!

FixedDocument fd = new FixedDocument();
PageContent pc = new PageContent();
fd.Pages.Add(pc);
FixedPage fp = new FixedPage();
((IAddChild)pc).AddChild(fp);
TextBlock tb = new TextBlock();
tb.Text = "Page one";
fp.Children.Add(tb);

Once the FixedDocument is constructed in memory it can be serialized to the package's stream via the XpsDocumentWriter.

XpsDocumentWriter dw =
	XpsDocument.CreateXpsDocumentWriter(doc);
dw.Write(fd);

And that's it.  The only thing to worry about is our MemoryStream object.  Once its disposed, our PackageStore cannot access the parts within the XPS document package.  This means that as long as you wish to manipulate the XPS document you've just created (including viewing it), you must keep the stream open.  Once you are done with the XPS document (e.g., its being discarded or it has been saved to disk) you can dispose of the stream.

The code for this post is included in a working sample project here:


Tags:
Categories: WPF | XAML | XPS
Actions: E-mail | Permalink | Comments (4) | Comment RSSRSS comment feed

A Quick Introduction to XPS

March 4, 2008 08:37 by will

XPS, or the XML Paper Specification, is a (relatively) new document format developed by Microsoft.  XPS is analogous to PDF; both are fixed document formats designed to be platform-independent.  Being fixed, the layout of the document is set at design time and, hypothetically, should remain the same no matter what device produces the document.  While PDFs are based on PostScript, an ancient and crusty language used to plot mammoths and gazelle on cave walls, XPS documents are described using XAML, a superset of the hyper-modern and streamlined (that's why everything is surrounded with < >'s--to keep down on wind resistance) XML.

The primary benefit of describing XPS documents in XAML is that XAML maps directly to objects, their properties and events.  This means that there is a built in document object model (DOM) that can be used to create, load, parse, modify and save XPS documents in memory at runtime.

One of the biggest problems facing developers when trying to learn how to use XPS documents is that the current documentation on MSDN about XPS documents is utter crap.  Hopefully, it will get better.  But until then...

Up next, a quick overview of the DOM, and creating XPS documents in memory. 


Tags:
Categories: WPF | XAML | XPS
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed