#1,174 – Custom Panel, part VI (Attached Properties)
October 7, 2014 1 Comment
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>
Pingback: Dew Drop – October 7, 2014 (#1871) | Morning Dew