Adam
Adam

Reputation: 1011

Internal management of DependencyProperty value and Changed callbacks

I think this is a basic misunderstanding about how to manage dependency properties but I can't seem to find a clear example to correct me.

Looking at the following code as an example...

public class MyControl
{
    public static readonly DependencyProperty ExpressionProperty = 
                                    DependencyProperty.Register("Expression",
                                    typeof (Expression),
                                    typeof (MyControl),
                                    new PropertyMetadata(ExpressionChanged));

    public Expression Expression
    {
        get { return (Expression)GetValue(ExpressionProperty); }
        set { SetValue(ExpressionProperty, value); }
    }

    private static void ExpressionChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        ... Must respond to external change of property
        ... Update UI to reflect external change to property
    }

    private void RespondToInput()
    {
        ... Do something to expression, add new elements or something
        ... Now expression has changed so I want to update the dependency property
        ... so datacontext gets new value.
        SetValue(ExpressionProperty, updatedExpression);
    }
}

What I don't understand is that when I do the RespondToInput work, I want to now update the DependencyProperty, but if I do, the PropertyChanged callback is called, at which point I go in a circle and now start updating the UI, even though I initiated the change from the UI effectively.

I don't know if that makes enough sense.

What did I do wrong??

Thanks!

Upvotes: 1

Views: 541

Answers (1)

Clemens
Clemens

Reputation: 128096

You can't prevent the PropertyChangedCallback from being called when the property value changes. What you can do is not to react on an internal property change:

private bool isInternalExpressionChanged;

private static void ExpressionChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
    if (!isInternalExpressionChanged)
    {
        ...
    }
}

private void RespondToInput()
{
    ...
    isInternalExpressionChanged = true;
    SetValue(ExpressionProperty, updatedExpression);
    isInternalExpressionChanged = false;
}

Upvotes: 1

Related Questions