XAML Binding Dynamically to the Size of a Child Control

by mheydt 4. April 2008 01:17 >
Here's a little XAML trick for when you are trying to dynamically size a display element based upon the size of another element.  This is useful when you need to resize a parent element based upon the size of it's content, but where the parent element may also be incorrectly sized due to its being a part of another control such as a grid.

For example, I am building a small control that will be used as a header on a window that consists of three components, a set of window control buttons (min, max, close) that are left justified, a menu that is right justified, and a caption (some text) that spans the entire space between the two other elements.

The window controls are a fixed size, but the menu can be a variable size depending upon the number of items that are in the menu which may not be know until run-time.

A naive attempt (like I did at first being used to tables in HTML) at declaring this in XAML would use a grid declared like this:


The problem with this as that the layout engine will split the width of columns 1 and 2 to be even in width, which renders something that looks like this:



Not exactly what I expected, as I was hoping that the layout engine would only make the column for the menu as wide as the menu, and splitting the second column with the width therefore made the caption too small and only filling about half of the area I wanted.

There are potentially a number of ways to solve this (including code behind to handle ArrangeOverride and MeasureOverride events), but the simplest way is to bind the width of the thrid column to the ActualWidth property of the menu control.  This changes the column definitions in the grid to the following:


Which makes the window look like this:



Which is just what I wanted!

How/why this works is due to the hierarchical and multi-pass nature of the WPF engine, and the integration to data binding.  Basically, the control will lay itself out and the grid will define the two columns to be of equal width.  After that, but prior to rendering, the data binding engine will read the value of the ActualWidth property of the menu control (which has been decided already through the just completed layout process) and assign it to the Width property of the right-most column, which will also cause the middle column to resize to take up that space.

And all of that with just a few lines of markup!

Tags:

.Net | WPF

blog comments powered by Disqus

about the author

I'm a .NET, XAML, and iOS polyglot that loves playing with new things and making cool and innovative stuff.  I am also a Mac junkie.

I am Principal Technologist for SunGard Global Services in NYC, in their Advanced Technologies practice, and I work extensively with SunGard's energy and financial customers.

Note the the posting on this blog are my own and do not represent the position, strategies or opinions of SGS.

recent comments

None

month list