#1,173 – Custom Panel, part V (Two Columns)

Below is another example of a custom panel.  This panel arranges its children into two columns, flowing to the next row after both columns are filled.  It also gives each child element a uniform amount of space, based on the total size of the containing panel.

    public class TwoColUniformPanel : Panel
    {
        protected override Size MeasureOverride(Size availableSize)
        {
            Size childSize = CalcUniformChildSize(availableSize);

            foreach (UIElement elem in InternalChildren)
                elem.Measure(childSize);

            return availableSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            // All children are the same size
            Size childSize = CalcUniformChildSize(finalSize);

            double top = 0.0;
            double left = 0.0;

            for (int i = 0; i < InternalChildren.Count; i++)
            {
                Rect r = new Rect(new Point(left, top), childSize);

                InternalChildren[i].Arrange(r);

                // Next row
                if (left > 0.0)
                    top += childSize.Height;

                // Alternate column
                left = (left > 0.0) ? 0.0 : (finalSize.Width / 2.0);
            }

            return finalSize;
        }

        private Size CalcUniformChildSize(Size availSize)
        {
            int numRows = (int)Math.Ceiling(InternalChildren.Count / 2.0);
            return new Size(availSize.Width / 2.0,
                            availSize.Height / numRows);
        }
    }

We can use the panel as follows:

    <loc:TwoColUniformPanel Margin="5">
        <Label Content="I'm child #1" VerticalAlignment="Center"
               Background="Thistle" />
        <Label Content="I'm child #2"
               Background="Lavender" />
        <Label Content="Third kid"
               Background="Honeydew" />
    </loc:TwoColUniformPanel>

Below are some images showing the result, as we resize the panel. Note that the first label stays vertically aligned in the center of the area allotted for it, rather than stretching to fill the area like the other labels.

1173-001

1173-002

1173-003

About Sean
Software developer in the Twin Cities area, passionate about .NET technologies. Equally passionate about my own personal projects related to family history and preservation of family stories and photos.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: