I really like WPF. It's the best layout technology I've seen yet out of Microsoft. But most of the time I want my controls to take up all of the available space, and that leaves me two choices of built-in panels. First there's
DockPanel, which doesn't work if I want to distribute the space between more than one control (and its requirement that the stretched control be the last child can lead to some strange XAML). Then there's the
Grid, which can do it all, but its requirement that you define all of your rows and columns up front seems too verbose to me, especially if I only want a single row or column.
Having decided to implement my own Panel, I returned to my first love: wxWidgets. wxWidgets uses Sizers for layout, and in particular there are two that are relatively simple yet allow you to do most things you'd want to do: wxBoxSizer and wxFlexGridSizer.
The concept of the
BoxSizer class (based on
wxBoxSizer) is pretty simple. It's very similar to a
StackPanel in that it lines up its children in the
Orientation direction and lets them be as big as they want in the other direction. However, it also provides a
Proportion attached property for its children. All of the leftover space in the
Orientation direction is divided up among the children that have a non-zero proportion. For simplicity in this article, we'll develop a sizer with fixed Orientation (Horizontal), but the download uses an
Orientation property just like the
The Proportion Attached Property
An attached property allows us to essentially add properties to other classes. We'll need one of these so our children can tell us what proportion they want to have. The first step is to register the attached property. This involves telling the framework what the type of the property is, what our type is, and what the default value is. We can also tell the framework that it needs to re-evaluate the layout when the property changes.