Using a DependencyProperty ChangedCallback as a validation measure I have an UserControl where I declare two DependencyProperties

int? Level;
CardBase SelectedCardBase;


A non-null CardBase object will always have 2 read-only integers: MinLevel and MaxLevel.

The UserControl allows the user to change as he desires both DPs, and the internal logic must ensure that both DPs have valid values following these rules:


If SelectedCardBase is null, then Level must be null.
If SelectedCardBase is not null, then Level must be between MinLevel and MaxLevel.
When SelectedCardBase changes to anything but null, Level is set to MaxLevel.


This is the code:

    public CardBase SelectedCardBase
    {
        get { return (CardBase)GetValue(SelectedCardBaseProperty); }
        set { SetValue(SelectedCardBaseProperty, value); }
    }

    public static readonly DependencyProperty SelectedCardBaseProperty = 
         DependencyProperty.Register("SelectedCardBase", typeof(CardBase), typeof(MyUserControl), 
         new PropertyMetadata(null, new PropertyChangedCallback(SelectedCardBaseChanged)));        

    private static void SelectedCardBaseChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (e.NewValue == null)
            d.SetValue(LevelProperty, null);
        else
            d.SetValue(LevelProperty, ((CardBase)e.NewValue).MaxLevel);
    }

    public int? Level
    {
        get { return (int?)GetValue(LevelProperty); }
        set { SetValue(LevelProperty, value); }
    }
    public static readonly DependencyProperty LevelProperty =
        DependencyProperty.Register("Level", typeof(int?), typeof(MyUserControl), 
        new PropertyMetadata(null, new PropertyChangedCallback(LevelChanged)));
    private static void LevelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CardBase card = (CardBase)d.GetValue(SelectedCardBaseProperty);

        if (card == null)
        {
            if (e.NewValue != null)
                d.SetValue(LevelProperty, null);
        }
        else if (e.NewValue == null)
        {
            d.SetValue(LevelProperty, e.OldValue);
        }
        else
        {
            int level = (int)e.NewValue;

            if (level &lt; card.MinLevel)
                d.SetValue(LevelProperty, card.MinLevel);
            else if (level &gt; card.MaxLevel)
                d.SetValue(LevelProperty, card.MaxLevel);
        }
    }


I don't fully get how CoerceValueCallbacks work, and I've read (or misunderstood) that both Coerce and Changed callbacks can be overwritten because they are metadata, so my questions are:


What problems (if they exist) will I have when something subscribes to the OnValueChanged of one of those DP?
Should I use CoerceValueCallbacks instead of this? 
If so, what is the correct way of doing this using CoerceValueCallbacks? 
And of course, with the given rules at the beginning, there is any mistake on the  code that would cause strange behaviour, or anything that could be improved?
Yes, you should use CoerceValueCallback instead to coerce your Level property (what you are trying to do is not "validation" strictly speaking).

private static object CoerceLevel(DependencyObject d, object value)
{
    var control = (MyUserControl)d;
    if (control.SelectedCard == null) return null;
    var level = (int?)value;
    if (level.HasValue) 
    { 
        return Math.Min(Math.Max(level.Value, control.SelectedCard.MinLevel), control.SelectedCard.MaxLevel);
    }
    else
    {
        return control.Level;
        //or 
        //return DependencyProperty.UnsetValue;
    }
}