Charles Petzold



Rewiring Our Graphics Brains

December 29, 2005
A Rainy Roscoe, NY

In the early days of Windows, it was common to see applications that sometimes left "holes" in their windows because the developers hadn't learned how to retain all the information necessary to refresh their displays during WM_PAINT. We all had to rewire our brains a bit to accomodate Windows graphics redrawing protocols.

We're rewiring our brains again with WPF, and I'm continuing to explore the nature of using retained graphics. Here's a LetItSnow.csproj project file and a LetItSnow.cs source code file that implements a timer-driven Koch Snowflake. (See http://mathworld.wolfram.com/KochSnowflake.html for much more mathematical background than you need to understand the program.)

The constructor of the window creates a Polygon object (from the System.Windows.Shapes namespace) and gives the Points collection three Point objects that define a triangle. Then, once per second, the TimerOnTick method inserts three more points into the Points collection to add a "bump" to each edge in sequence. I'm not sure how long you want to let this program run, but there are a couple observations we can make regardless:

First, each time the Points collection is changed, the filled polygon is redrawn without any flicker whatsoever. Not even the mouse cursor blinks when you hold it directly over an area being redrawn!

Secondly, there's a different mechanism at work in this program than the one normally encountered in animations and programs like DrawCircles. Normally what changes is a property of the object that is backed by a dependency property. (For example, the Width and Height properties defined by FrameworkElement are backed by the DependencyProperty fields WidthProperty and HeightProperty. It is metadata attached to these dependency properties that indicates if a change in the Width and Height properties require a change in layout or rendering.)

Yes, the Points property of Polygon is backed by the dependency property PointsProperty, but the LetItSnow program isn't changing the Points property. It's changing the PointCollection object referenced by the Points property. I am much less confused that I'd be otherwise because PointCollection derives from Freezable and hence includes a Changed event. It is possible for any class using a PointCollection object to be notified of changes to that collection but, as I said, it's evidently a somewhat more specific mechanism at play than the generalized dependency property metadata.