#1,174 – Custom Panel, part VI (Attached Properties)

You can define an attached dependency property in a custom panel.  The attached property can be used by child elements of the panel and in a way that affects how the child elements are laid out.  In the example below, we define a boolean SecondColumn property.  If set, this property indicates that a child element should appear in a second column.

    public class TwoColPanel : Panel
    {
        private static FrameworkPropertyMetadata secColMetadata =
            new FrameworkPropertyMetadata(false,
                FrameworkPropertyMetadataOptions.AffectsParentArrange);

        public static readonly DependencyProperty SecondColumnProperty =
            DependencyProperty.RegisterAttached("SecondColumn", typeof(bool),
                typeof(TwoColPanel), secColMetadata);

        public static void SetSecondColumn(DependencyObject depObj, bool value)
        {
            depObj.SetValue(SecondColumnProperty, value);
        }

        protected override Size MeasureOverride(Size availableSize)
        {
            foreach (UIElement elem in InternalChildren)
                elem.Measure(availableSize);

            return availableSize;
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            double topCol1 = 0.0;
            double topCol2 = 0.0;

            for (int i = 0; i < InternalChildren.Count; i++)
            {
                bool col2 = (bool)InternalChildren[i].GetValue(SecondColumnProperty);

                double left = col2 ? (finalSize.Width / 2.0) : 0.0;
                double top = col2 ? topCol2 : topCol1;

                Rect r = new Rect(new Point(left, top),
                                  InternalChildren[i].DesiredSize);

                InternalChildren[i].Arrange(r);

                if (col2)
                    topCol2 += InternalChildren[i].DesiredSize.Height;
                else
                    topCol1 += InternalChildren[i].DesiredSize.Height;
            }

            return finalSize;
        }
    }

We use the attached property as follows:

    <loc:TwoColPanel Margin="5">
        <Label Content="I'm child #1" loc:TwoColPanel.SecondColumn="True"
               Background="Thistle" />
        <Label Content="I'm child #2" loc:TwoColPanel.SecondColumn="False"
               Background="Lavender" />
        <Label Content="Third kid"
               Background="Honeydew" />
    </loc:TwoColPanel>

1174-001

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.

One Response to #1,174 – Custom Panel, part VI (Attached Properties)

  1. Pingback: Dew Drop – October 7, 2014 (#1871) | Morning Dew

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: