Saturday 18 June 2011

Silverlight and WPF Measurement Pain

One of the more irritating things I've been dealing with in Silverlight and WPF is that sizing and automatic content placement is a pain. Don't get me wrong -- I love the new rendering engine and how it works to update the layout, but it can be a pain to "think in terms of WPF or Silverlight." Especially when the two don't exactly have the same methods of working.

I made a decision fairly early on to build a static Utilities class, which holds all of my ugly code where I have to use the very, very, very fun

#if SILVERLIGHT            

#else

#endif

constructs, which gets me to the point of this post.

It's difficult to determine the size of a control -- especially the size it wants to be. Ideally, yes, the DesiredSize will have that exact size. Unfortunately, the DesiredSize is somewhat misleading -- it's the DesiredSize of the space it's confined to. In addition, it works totally different between Silverlight and WPF.

I was primarily concerned with sizing things before they are rendered (they have no parent). This is drastically different from figuring out a size once they are in the layout tree and the control itself has a parent.

In any case, I'm only going to cover the basics. The most simple way to determine the size something wants to take up is to do artificially measure the element and then check the desired size. Assuming I have a TextBlock named Frank, the following code would determine the size Frank really wants:

Frank.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
Frank.Height = Frank.DesiredSize.Height;
Frank.Width = Frank.DesiredSize.Width;

Ah, a crafty trick (and it works in both Silverlight and WPF without a hitch; if Frank didn't have a parent, the code would be different between the two platforms). We make the control believe it has unlimited space, and then we can use DesiredSize. Play with it a little bit -- set a breakpoint on DesiredSize before and after this call and see the difference.

For more information about how the Layout system works (which is an excellent read for understanding how WPF/Silverlight work), check out this MSDN article: http://msdn.microsoft.com/en-us/library/ms745058.aspx