Charles Petzold



Why I Structured My Book Like I Did

March 5, 2007
New York, N.Y.

A programmer named Ben Hayat writes in an email:

I spend a lot of time and energy organizing the material in my books. I draw big dependency diagrams on white boards; I make index cards for various topics and then lay them out on the floor in various experimental orders; I write sketchy early versions of half a dozen chapters to test if the material flows correctly. The ordering of material is a central problem in writing a programming tutorial, and I struggle to get it right. I want each chapter to progressively build on the last, like bricks in a wall of knowledge.

Applications = Code + Markup: A Guide to the Microsoft Windows Presentation Foundation presented a very special challenge. As the title implies, WPF applications are generally built from both procedural code (most often C#) and the XML-based Extendable Application Markup Language (XAML).

Between the time I signed the contract for the book (spring 2003) and the day I commenced full-time work on the WPF book (September 5, 2005, as this blog entry documents), I toyed around with all three approaches to covering C# and XAML in the book:

By "toyed around" I mean sketching out possible chapters, exploring topic dependencies, writing a few paragraphs here and there to see how it would work.

The last of these three options actually intrigued me a great deal. I thought I could begin with XAML as if it were an HTML-like language for Windows client programming, and then actually cover a great deal of XAML before the necessity of introducing event handling. It additionally thrilled me a bit to think that the book might even tap an elusive segment of the market: People who might know a little HTML and would program as well if only they were introduced to the concepts correctly. I kept a close eye on one very special feature: the ability to embed C# code in a stand-alone XAML file and have it run in the browser. Although this feature was hinted at a bit, it never became real. If it had become real, I might have gone this route — or at least seriously considered it.

At the time I signed the contract for the book, I thought I'd be covering C# and XAML in tandem: Here's how to do something in C#. Here's the equivalent XAML. Here's what you can only do in code. Here's how you integrate the code and XAML. (In fact, the description of the book on Amazon still indicates that's how the book is structured. The blurb was taken from my early proposal and apparently never changed, alas.) But by the time I started the book, I had changed my mind, as this blog entry documents.

As Ben Hayat notes, the other authors of WPF books decided differently. Obviously I can't address the rationale behind their decisions. (Perhaps they will?) But I can make some observations:

If an author decides to use the canned Visual Studio projects and designer, he's kind of stuck into the particular coding scheme that Visual Studio imposes. Create a WPF Windows Application in Visual Studio and you get two C# files, two XAML files (plus three more C# files, a .resx file and a .settings file tucked away in a Properties directory). So there you are, and that's what you need to discuss. It's irrelevant whether your best instincts as an author have convinced you not to discuss both C# and XAML in your first chapter. Visual Studio says that you must, and Visual Studio is the boss.

For those of us who teach programming and APIs, Visual Studio has increasingly become a big problem. Although virtually everyone uses Visual Studio (including me, of course), I think it's a disaster for actually teaching programming, and I've expressed my doubts about its influence over programming practices elsewhere.

Another possible issue: The WPF developers at Microsoft are very proud of XAML, as well they should be. But this pride tends to distort their view of the totality of the WPF API. XAML is particularly seductive for presentations and demos. You can do a whole presentation or video webcast just by running XAMLPad (or my own XAML Cruncher), typing in XAML, and seeing the results. XAML is so sexy that introducing a little code into the presentation seems to blow away all the fun.

About two years ago, I went to Redmond to attend a three-day WPF System Design Review. (At the time it was called the Avalon System Design Review.) Three days of WPF, and it was nearly all XAML. It was all very interesting, to be sure, but there was virtually nothing covered about event handling, for example. As we all know, when you're writing an actual application, almost everything is event handling. In the vast scheme of things, XAML does very little except replace a constructor of a Window class (and possibly replace a few special kinds of event handlers if you're using data binding or animation).

The more I explored XAML on my own, the less I seemed to know. How do panels work? Why were some properties bindable but others were not? Why were some properties animatable but others were not? Why do those properties called "attached properties" seem to be in the wrong place? Why can you specify an event handler for children in a parent's tag? What happens when modifying an existing control with a template isn't enough and you need to write a custom control with keyboard and mouse handling and drawing?

Of course, answering these questions for myself required a lot of exploration. XAML is not as simple as it first seems. XAML required a whole intrastructure in WPF that involves layout mechanisms, dependency properties, routed events, and other features. It became quite obvious that most WPF programmers would want a familiarity with this infrastructure. Most WPF programmers would also want to gain a facility for working with this infrastructure. This can only be achieved in code.

Just one example: If you see an attached property in XAML — such as Grid.Row="2" — it really doesn't make a lot of sense. You're specifying a property of the Grid panel within a child element of the Grid. If you look at the syntax in code, however, and you're given an explanation of what's going on behind the scenes in the context of alternative syntax, then attached properties make perfect sense.

I made a decision to tackle a lot of the WPF infrastructure very early in the book. I have an early chapter on dependency properties and a chapter on routed input events. I show how to write custom elements and custom panels comparatively early in the book. Many of my sample programs contain Window constructors that create and intialize elements and controls, which is a job that is eventually taken over by XAML, but doing it in code is something that every WPF programmer should know. Some stuff — such as defining a template — is incredibly painful in C#, but my book shows examples of that as well, and I hope the reader later comes to appreciate the relative simplicity of doing it in XAML.

I also decided to develop a XAMLPad-like application in my book. It's called XAML Cruncher, and it's built on top of a fully-functional Notepad clone also presented in the book. (Apparently people who complain that the book has "no applications" haven't gotten that far.) Once I made the decision involving XAML Cruncher, the idea of first covering C# syntax appealed to me even more. In one sense, the whole thrust of the first part of the book is to develop XAML Cruncher, at which point you have a tool (complete with source code) that lets you explore XAML in an interactive manner.

In any book I write, one of my constant goals is to demystify the API. Anything that seems like "magic" is a target for me. There is too much magic in XAML, too much the aspiring WPF programmer needs to accept on pure faith about XAML when simply incorporating it into a Visual Studio project. That's why the first program in my book that combines C# and XAML (the LoadEmbeddedXaml program on page 463) uses XamlReader.Load to convert a snippet of XAML into an object. This may seem a perverse approach, but XamlReader.Load certainly helped to demystify XAML for me. (XAMLPad itself seemed like magic the first time I saw it, but XAMLPad also does it's "magic" with XamlReader.Load)

As anyone knows who has followed my blog entries over the past year or so, my love for XAML is second to no one's. XAML is lots of fun, and it's great doing little demo programs entirely in XAML. But XAML is like crack. Once you get into a XAML-only mindset, your entire world gets smaller and smaller. You're doing cute demos, but you're not doing real-life WPF programming. Real-life programming is code. We use code because it's flexible and can do pretty much anything we want. XAML doesn't have for loops or if statements, and only if you use techniques that I pioneered in blog entries here and here, can you do any arithmetic in XAML. XAML is great for what XAML is great for, but that's about it.

If I had to write the book all over again, I'd do a few things differently: I'd definitely put a bunch of screen shots in the book. Not doing screen shots was a mistake. Although I came up with the title of the book, I am still plagued with self-doubt about it. Perhaps something a little less "artsy" would have been appropriate. But I'd still structure the book the same way because I think my coverage of the C# API and the WPF intrastructure provide an excellent foundation for eventually incorporating XAML into your WPF applications.

Reading a thousand-page book all the way through requires a big commitment and a lot of trust in the author. "If I devote the time, will the author deliver the goods?" My book was not written for reference or for skipping around. It is a complete tutorial intended to be read from beginning to end, and if my decisions seem perverse ("Chapter 2 covers brushes????"), rest assured that my choices were not arbitrary, but instead the result of dedicated thought and consideration. I know what I'm doing. I've been writing books like this for 20 years.

Applications = Code + Markup is hardcore: It's for programmers who seriously want to learn the intrastructure and application of WPF — both in code and XAML.