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
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(...).