Charles Petzold

Thinking Differently with WPF

December 22, 2005
Roscoe, NY

Some basic things you sometimes need to do in a Windows program — such as drawing in response to mouse movement — don't seem straightforward at all in the Windows Presentation Foundation. There doesn't appear to be anything equivalent to getting a DC or a Graphics object and just drawing.

WPF requires us to think a little differently about these things. If you want to draw in response to the mouse, you probably want to do so on the surface of a Canvas, which is the only type of panel that allows precise positioning of elements. On receipt of a button-down event, you can then create an object of the desired type and add it to the Canvas child collection. If you're lucky, "an object of the desired type" will be a class that inherits from Shape, which includes Line, Rectangle, Ellipse, Polyline, Polygon, and Path. During subsequent MouseMove events, you can then dynamically modify the properties of this object — moving it, changing its size, changing colors, whatever.

In Windows API programming, and even in Windows Forms, drawing during mouse-moves is fairly low-level stuff. In Windows Forms, you have the additional problem of no raster operations to prevent flickering. In WPF, however, all the actual rendering (and the retention of the object in the Canvas child collection) is handled for you. The extra bonus is that hit-testing and later changes to the properties of the Shape objects verges on the trivial.

Today, for my user-input chapter (which occurs about halfway through Part 1 and mostly exists to discuss routed events), I wrote a program I called DrawCircles to illustrate this technique. (For some odd reason, the name of every sample program in the book begins with a verb.) The DrawCircles.csproj and DrawCircles.cs files should be enough to compile and run this program under the November CTP (and, I'm sure, the December CTP but I'm a little behind) with the SDK and extensions to Visual Studio 2005 installed.

Use the left mouse button to draw circles in the window. Use the right mouse button to move an existing circle. Use the middle mouse button to toggle the interior between red and transparent.

If you notice a few inconsistencies — for example, the program captures the mouse when drawing but not when dragging — that's only because I'm using the program in the book to illustrate a couple different mouse-handling techniques.

Progress Report: Today I got past the 250-pages mark (that's book pages). Based on my 5-pages-per-calendar-day-beginning-on-November-1 quota, I'm two days behind, which ain't too bad. I may miss a few days of work this weekend, however. There's a holiday coming up, and according to Fox News, if I celebrate this holiday with insufficient enthusiasm, I could be liable for arrest under new provisions of the Patriot Act. (And they have ways of finding out.)