IanG on Tap

Ian Griffiths in Weblog Form (RSS 2.0)

Blog Navigation

April (2018)

(1 item)

August (2014)

(1 item)

July (2014)

(5 items)

April (2014)

(1 item)

March (2014)

(1 item)

January (2014)

(2 items)

November (2013)

(2 items)

July (2013)

(4 items)

April (2013)

(1 item)

February (2013)

(6 items)

September (2011)

(2 items)

November (2010)

(4 items)

September (2010)

(1 item)

August (2010)

(4 items)

July (2010)

(2 items)

September (2009)

(1 item)

June (2009)

(1 item)

April (2009)

(1 item)

November (2008)

(1 item)

October (2008)

(1 item)

September (2008)

(1 item)

July (2008)

(1 item)

June (2008)

(1 item)

May (2008)

(2 items)

April (2008)

(2 items)

March (2008)

(5 items)

January (2008)

(3 items)

December (2007)

(1 item)

November (2007)

(1 item)

October (2007)

(1 item)

September (2007)

(3 items)

August (2007)

(1 item)

July (2007)

(1 item)

June (2007)

(2 items)

May (2007)

(8 items)

April (2007)

(2 items)

March (2007)

(7 items)

February (2007)

(2 items)

January (2007)

(2 items)

November (2006)

(1 item)

October (2006)

(2 items)

September (2006)

(1 item)

June (2006)

(2 items)

May (2006)

(4 items)

April (2006)

(1 item)

March (2006)

(5 items)

January (2006)

(1 item)

December (2005)

(3 items)

November (2005)

(2 items)

October (2005)

(2 items)

September (2005)

(8 items)

August (2005)

(7 items)

June (2005)

(3 items)

May (2005)

(7 items)

April (2005)

(6 items)

March (2005)

(1 item)

February (2005)

(2 items)

January (2005)

(5 items)

December (2004)

(5 items)

November (2004)

(7 items)

October (2004)

(3 items)

September (2004)

(7 items)

August (2004)

(16 items)

July (2004)

(10 items)

June (2004)

(27 items)

May (2004)

(15 items)

April (2004)

(15 items)

March (2004)

(13 items)

February (2004)

(16 items)

January (2004)

(15 items)

Blog Home

RSS 2.0

Writing

Programming C# 5.0

Programming WPF

Other Sites

Interact Software

WPF MSDN Browser

Wednesday 21 June, 2006, 02:09 PM

Craig Andera recently blogged about the MTPS Content Service. This is a web service provided by Microsoft that lets you retrieve MSDN content. Craig also showed an example application based on this service called msdnman. This is a command-line utility for viewing help pages from MSDN.

Being a WPF guy, I thought I'd take a crack at writing a WPF viewer based on the same web service. This is something I've long wanted to see. In fact the Windows SDK already includes an SDK Viewer WPF Example, but that relies on a local copy of the content, pre-translated into WPF FlowDocuments. I want something that uses the real content direct from the web server.

Why would this be useful? What does it add beyond what the built-in help viewer already provides? The main advantage is the ability to use WPF's reading technology. The built-in SDK Viewer is based on HTML, so it sometimes does a poor job of using the available width. If you let the standard viewer fill your screen, lines of text will be as wide as the screen. Lines this long are very hard to read. The longer the lines are, the more likely you are to miss when looking for the start of the next line. This makes for a tiring and unsatisfactory reading experience.

This is why WPF offers a column-based reading experience. We know from experience in the print world that breaking text into columns can make it much easier to read. Indeed, once you've got used to reading in columns, going back to the long unbroken lines offered by the standard SDK viewer feels like punishment!

Here's an example of what it looks like:

WPF MSDN Reader

Paging vs. Scrolling

At first, the use of paging rather than scrolling feels a little odd. However, it is necessary because columns and scrolling really don't get on well together. (As you'll know if you've ever tried to read a PDF formatted with columns taller than your screen. Columns only make sense when the column heights match the viewing area.) However, you soon get used to it. After all, printed media has worked this way for some time now!

I've found that it takes a little experimentation to get the best layout. WPF seems happy to use columns that are a little narrower than I would like. I prefer the way it looks when I've got the window at a width where the columns are about as wide as WPF will let them go before it adds an extra column.

There's one thing I really wish this column-based view would do: I want to be able to move through the text one column at a time rather than one page at a time. If a page break happens to come at an inconvenient point in the narrative, I just have to put up with that. (Compare that to scrolling, where you can choose the region to make visible.) If I could page along one column at a time, it would give me more control over the context of what I'm reading.

Also, there are issues with tables. It turns out that while columns make prose much easier to read, it's a really bad idea to put big tables in narrow columns. This problem means that some pages, such as the Member Lists, are completely unusable. Also, some code samples don't get on that well with a column-based layout.

This is why in magazines, the prose is in columns but tables and code samples are usually presented as figures, enabling them to use more width. WPF's document handling does actually allow for this: you can add figures that can span multiple columns. But I've simply not written the code to do that in this example.

The Code

The code is based on Craig's msdnman. And like msdnman, it's open source, released under the MIT license.

One difference between Craig's code and mine is that I decided to try using WCF to talk to the MTPS service. (Craig's code uses.NET 2.0 era web service wrappers. I figured that since I'm using WPF, I may as well go the whole .NET 3.0 hog.) I'm using beta 2 bits, and hit one problem with the proxy generated by WCF's Add Service Reference feature in Visual Studio 2005. One of the types this imports is called primary, which has a property called Any. This is where the document content will come back. The proxy generator marked this with an XmlAnyElementAttribute, which is correct, but it also added (Order=0). For some reason this causes the Any property always to be null. I had to delete the (Order=0) to get things working. I'm guessing this is just a quirk of the current beta.

Try It

Please bear in mind that this example is just a proof of concept. There are lots of problems with it. For example, it's missing a Back button. It ignores images completely. And as mentioned, it doesn't deal well with tables.

One last thing. This example assumes that you have the Consolas font. It uses it for the code snippet sections. Without that, those will come out in some default proportional typeface. Either download and install Consolas, or modify the CodeSnippet style in App.xaml.

You can download the source from here, or the binary from here. This is built for beta 2 of WinFX. (Yes, I know it's called .NET 3.0 now, but it was still called WinFX when beta 2 was released.)

Enjoy!

Copyright © 2002-2024, Interact Software Ltd. Content by Ian Griffiths. Please direct all Web site inquiries to webmaster@interact-sw.co.uk