Karsten Extracts My Templates (Ouch!)
January 27, 2006
New York, N.Y.
Like a dentist wielding a pair of Lock-Vise pliers, Karsten Januszewski demonstrates how to extract deeply-rooted templates from the jaws of recalcitrant XAML files and use them in your own programs with the help of Expression Blend. As examples, I am honored that he uses some templates I wrote for an article in MSDN Magazine.
And of course he discovered the big problem in my beloved 3D Slider: Because I link a rotation angle to the Value property of the Slider, I was forced to hard-code the Minimum and Maximum properties at -25 and 25, which is a very uncool thing to do. But I couldn't see any way around it while maintaining a pure-XAML approach, so I let it go and hoped that a range of -25 to 25 would now become the industry strandard for Slider code.
Between the time I submitted the article and the time the issue came out, I occasionally took a shot at trying to fix it. After all, my one claim to the XAML Hall of Fame is pioneering a technique to do arbitrary additions and multiplications in XAML (see here and here) so this should be right up my alley. But the required formula is something like this:
-
Rotation Angle = -25 + 50 * (Value - Minimum) / (Maximum - Minimum)
Notice the division. Divisions are real hard to do in XAML. Probably the closest you can come is a technique that only allows division by an integer, and that's creating a UniformGrid with one child, and setting the Width of the UniformGrid equal to the dividend and Columns equal to the divisor. The quotient is the ActualWidth of the child element. (I've never actually written a XAML file that uses this technique, but it seems sound enough if the numbers are within reason.)
One night I awoke from a restless sleep and said "Non-affine 3D transforms perform divisions" and that is true enough. (There's a recent book by Scott Rosenberg entitled Dreaming in Code; I sometimes have a tendency to be coding in my dreams, and I have never found the experience pleasant.) But in the light of day the technique crumbled, largely because Matrix3D is a structure and hence its properties aren't backed by dependency properties and conducive for binding, and also because the matrix would actually have to be applied to something to extract a division from it.
At this point, I give up. I think the right way to do it is to derive a class from Slider, add a get-only Angle property calculated as shown above, and use that in the XAML template.
Sometimes, you really need a little code.