Update UI in UWP Template Control when dependency property changes

1k Views Asked by At

I want template control that dynamically generates different shapes according to a dependency property.The control looks like this:

<Style TargetType="local:ColorShape">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:ColorShape">
                <ContentControl x:Name="shapeParent">
                </ContentControl>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

It has a depdency property for the shape: public ShapeType

ShapeType
{
    get { return (ShapeType)GetValue(ShapeTypeProperty); }
    set { SetValue(ShapeTypeProperty, value); }
}

public static readonly DependencyProperty ShapeTypeProperty =
    DependencyProperty.Register("ShapeType", typeof(ShapeType), typeof(ColorShape), new PropertyMetadata(ShapeType.Circle));

I generate the shape in the OnApplyTemplate method:

protected override void OnApplyTemplate()
{
    var shapeParent = (ContentControl)this.GetTemplateChild("shapeParent");
    var shape = GetShape(ShapeType);
    shapeParent.Content = shape;

    base.OnApplyTemplate();
}

I can DataBind the property, and it works the first time I create the control:

<Controls:ColorShape Grid.Row="1" Width="200" Height="200" Stroke="Black" ShapeType="{x:Bind ViewModel.Shape, Mode=OneWay}" StrokeThickness="5" Fill="{x:Bind ViewModel.Color, Mode=OneWay}" />

But if I modify the bound property in the ViewModel, that generates an INotifyPropertyChange notification but doesn't repaints the template control

I tried to add a callback in the dependency property of the template control, and I can see it refreshes the dependency property with the new values bound to the property (in this case ViewModel.Shape), but it doesn't refresh the UI (never calls again OnApplyTemplate). I tried to manually call ApplyTemplate method, and the event OnApplyTemplate doesn't get fired ever.

1

There are 1 best solutions below

1
Kai Brummund On BEST ANSWER

OnApplyTemplate is only called once, when the template is generated. It will only be called again, when you change the Template on the control.

What you need is a PropertyChangedCallback on the DependencyProperty:

public int MyProperty
{
    get { return (int)GetValue(MyPropertyProperty); }
    set { SetValue(MyPropertyProperty, value); }
}

public static readonly DependencyProperty MyPropertyProperty =
        DependencyProperty.Register("MyProperty", typeof(int), typeof(ownerclass), new PropertyMetadata(0, OnPropertyChanged);

private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    // Do what you need here
}

(The part you were missing is the second parameter at new PropertyMetadata(...).