I am trying to learn the basics of creating a custom panel in a WinRT XAML application. I have defined the attached dependency property, and it works as expected, except that I cannot figure out how to get the property callback for the child to trigger the location or dimension of the container.
How can a child let this container know that the arrangement and measurement should be called again? In my WPF 4 expandable book, they use FrameworkPropertyMetadataOptions.AffectsParentArrange, but this does not seem to be available in WinRT.
public class SimpleCanvas : Panel { #region Variables #region Left Property public static double GetLeft(UIElement element) { if (element == null) { throw new ArgumentNullException("element"); } object value = element.GetValue(LeftProperty); Type valueType = value.GetType(); return Convert.ToDouble(value); } public static void SetLeft(UIElement element, double value) { if (element == null) { throw new ArgumentNullException("element"); } element.SetValue(LeftProperty, value); } public static readonly DependencyProperty LeftProperty = DependencyProperty.RegisterAttached("Left", typeof(double), typeof(SimpleCanvas), new PropertyMetadata(0, OnLeftPropertyChanged)); public static void OnLeftPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) { UIElement element = (UIElement)source; // This doesn't cause ArrangeOverride below to be called element.InvalidateArrange(); } #endregion #region Top Property public static double GetTop(UIElement element) { if (element == null) { throw new ArgumentNullException("element"); } object value = element.GetValue(TopProperty); return (value == null) ? 0 : (double)value; } public static void SetTop(UIElement element, double value) { if (element == null) { throw new ArgumentNullException("element"); } element.SetValue(TopProperty, value); } public static readonly DependencyProperty TopProperty = DependencyProperty.RegisterAttached("Top", typeof(double), typeof(SimpleCanvas), new PropertyMetadata(0, OnTopPropertyChanged)); public static void OnTopPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) { UIElement element = (UIElement)source; // This doesn't cause ArrangeOverride below to be called element.InvalidateArrange(); } #endregion #endregion public SimpleCanvas() { } #region Methods protected override Size MeasureOverride(Size availableSize) { foreach (UIElement child in this.Children) { child.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity)); } return new Size(0, 0); } protected override Size ArrangeOverride(Size finalSize) { foreach (UIElement child in this.Children) { double x = 0; double y = 0; double left = GetLeft(child); double top = GetTop(child); if (!double.IsNaN(left)) { x = left; } if (!double.IsNaN(top)) { y = top; } child.Arrange(new Rect(new Point(x, y), child.DesiredSize)); } return finalSize; } #endregion }
source share