A Nifty Silverlight Feature

Today I stumbled across what I think is a nifty construct in Silverlight that you can use to control the size of a UI element.

Take a TextBox on a page that’s laid out with a Grid inside a ScrollViewer. This TextBox can take a lot of text so you set `TextWrapping=”Wrap”` but you find that as you type it just expands sideways ad infinitum rather than actually wrapping. This pushes everything in the Grid out of alignment and makes the page look very messy indeed.

It’s doing this because it’s inside a ScrollViewer which is designed to expand as necessary to cater for the controls it contains.

Now the text will wrap if you set the width of the TextBox explicitly, but you don’t want to do that as the layout needs to fluid enough to cope with different screen sizes. There is another property you can use “MaxWidth” – but what do you set this to? Again you can’t use a fixed value. Well if you do this:

Then the TextBox won’t grow beyond its current width and the text will wrap.

Obviously this will mean that if the page can grow sideways your TextBox won’t expand to fill the space, but it worked in this case as the ChildWindow it was in can’t grow.

If you want the MaxWidth to be more than the current width you can add a Converter:

So, why does this work? Well when the control is rendered the framework calculates it size and position from the data supplied directly in the XAML file and from the controls relationship to the other controls on the pages.

When it’s finished the “ActualHeight” and “ActualWidth” properties are updated. As these are DependencyProperties they send an Update message to the UI which means that we can use the value to set other properties on the same control.

Obviously, if we set the “Width” property in this way we’d potentially set up an infinite loop of updates cascading through the system so you have to take care!