The Question: By themselves, properties like Grid.Row, Grid.Column, Canvas.SetTop, etc. have great DesignTime support. You attach them to a child element, and watch the xaml update. How does their implementation differ from my example below?
The Example:
In this example I create an attached property called position. I can attach the position property to any child element in a grid. Doing so updates their row and column.
public static void SetPosition(DependencyObject obj, Positioning value) => obj.SetValue(PositionProperty, value);
public static void GetPosition(DependencyObject obj) => (Positioning)obj.GetValue(PositionProperty);
public static readonly DependencyProperty PositionProperty = DependencyProperty.RegisterAttatched( "Position", typeof(Positioning),
new PropertyMetadata( Positioning.Normal, OnPositionChanged));
public static void OnPositionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
UIElement item = obj as UIElement;
if(item == null)
return;
switch((Positioning) e.NewValue)
{
case Positioning.Middle:
Grid.SetRow(item, 4);
Grid.SetColumn(item, 2);
break;
default:
Grid.SetRow(item, 0);
Grid.SetColumn(item, 0);
}
}
//Usage:
<Rectangle local:Position="Middle" Fill="Pink" Height="40" Width="40"/>
This works at run time, but not at design time. My best guess is that maybe OnPositionChanged is not called at design time?
Things I've tried:
- calling a function when the attribute changes (see example above)
- adding attributes like FrameworkPropertyMetadataOptions.AffectsRender
- overriding the OnItemsChanged() function of an ItemsControl