Q:

Is it possible to have a usercontrol in WPF receive notification that a (multiple) property on a binded class has changed?

I have a usercontrol that uses several properties on a binded class.  I would like to update the control if any of the properties on this class change. 
INotifyPropertyChanged only works if I bind to the property directly.  (this will work but I would have to bind to several properties for each instance of the control)
Below is a striped down version of the issue I am having.  The DirectProperty works as expected.  The ParentPropertyChangedCallback() is only fired when the ParentClass is assigned to the user control, not when any of the properties change.
Please tell me I doing something stupid =)
UserControl1.xaml.cs
public partial class UserControl1
{
    public static readonly DependencyProperty DirectPropertyProperty =
        DependencyProperty.Register(
           "DirectProperty",
           typeof(bool),
           typeof(UserControl1),
           new PropertyMetadata(default(bool), DirectPropertyChangedCallBack));

    public static readonly DependencyProperty ParentClassProperty =
        DependencyProperty.Register(
            "ParentClass",
            typeof(ParentClass),
            typeof(UserControl1),
            new PropertyMetadata(default(ParentClass), ParentPropertyChangedCallback));

    public UserControl1()
    {
        InitializeComponent();
    }

    public bool DirectProperty
    {
        get { return (bool)GetValue(DirectPropertyProperty); }
        set { SetValue(DirectPropertyProperty, value); }
    }

    public ParentClass ParentClass
    {
        get { return (ParentClass)GetValue(ParentClassProperty); }
        set{ SetValue(ParentClassProperty, value); }
    }
    // private void parentProperty_Changed(object)
    private static void DirectPropertyChangedCallBack(
        DependencyObject dependencyObject,
        DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var sourceObject = dependencyObject as UserControl1;
        if (sourceObject == null) return;

        //set rectangle 1 base on Direct Property
        sourceObject.Rectangle1.Fill =
            sourceObject.ParentClass.DirectProperty
                ? new SolidColorBrush(Colors.Green)
                 : new SolidColorBrush(Colors.Red);
    }

    private static void ParentPropertyChangedCallback(
        DependencyObject dependencyObject,
        DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        var sourceObject = dependencyObject as UserControl1;
        if (sourceObject == null) return;

        //set rectangle 2 base on ParentClass Property
        sourceObject.Rectangle2.Fill =
            sourceObject.ParentClass.ParentProperty
                ? new SolidColorBrush(Colors.Green)
                : new SolidColorBrush(Colors.Red);

        //set rectangle 3 base on ChildClass Property
        sourceObject.Rectangle3.Fill =
            sourceObject.ParentClass.ChildClass.ChildProperty
                ? new SolidColorBrush(Colors.Green)
                : new SolidColorBrush(Colors.Red);

    }
}

ParentClass.cs
public class ParentClass :INotifyPropertyChanged
{
    private ChildClass _childClass;
    private bool _directProperty;
    private bool _parentProperty;
    public event PropertyChangedEventHandler PropertyChanged;

    public ChildClass ChildClass
    {
        get { return _childClass; }
        set
        {
            if (Equals(value, _childClass)) return;
            _childClass = value;
            OnPropertyChanged();
        }
    }
    public bool DirectProperty
    {
        get { return _directProperty; }
        set
        {
            if (value.Equals(_directProperty)) return;
            _directProperty = value;
            OnPropertyChanged();
        }
    }

    public bool ParentProperty
    {
        get { return _parentProperty; }
        set
        {
            if (value.Equals(_parentProperty)) return;
            _parentProperty = value;
            OnPropertyChanged();
        }
    }
    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

ChildClass.cs
public class ChildClass : INotifyPropertyChanged
{
    private bool _childProperty;
    public event PropertyChangedEventHandler PropertyChanged;

    public bool ChildProperty
    {
        get { return _childProperty; }
        set
        {
            if (value.Equals(_childProperty)) return;
            _childProperty = value;
            OnPropertyChanged();
        }
    }

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

**** Working Modified ParentClass
public class ParentClass :INotifyPropertyChanged
{
    private ChildClass _childClass;
    private bool _directProperty;
    private bool _parentProperty;
    public event PropertyChangedEventHandler PropertyChanged;

    public ParentClass()
    {
        PropertyChanged += OnPropertyChanged;
    }

    public ChildClass ChildClass
    {
        get { return _childClass; }
        set
        {
            if (Equals(value, _childClass)) return;
            _childClass = value;
            OnPropertyChanged();
            _childClass.PropertyChanged += OnPropertyChanged;
            DirectProperty = !DirectProperty;
        }
    }
    public bool DirectProperty
    {
        get { return _directProperty; }
        set
        {
            if (value.Equals(_directProperty)) return;
            _directProperty = value;
            OnPropertyChanged();
        }
    }

    public bool ParentProperty
    {
        get { return _parentProperty; }
        set
        {
            if (value.Equals(_parentProperty)) return;
            _parentProperty = value;
            OnPropertyChanged();
            DirectProperty = ! DirectProperty;
        }
    }
    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
    {
        if (propertyChangedEventArgs.PropertyName == "DirectProperty") return;
        // Properties that are bound to the UI you want to update
        DirectProperty = ! DirectProperty;
    }
}

A:

What you can do on your classes is to subscribe to property changed event. INotifyPropertyChanged gives you the ability to subscribe for PropertyChanges
    public ParentClass()
    {       
     this.PropertyChanged += OnPropertyChanged;
    }

    private void OnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
    {
        // Properties that are bound to the UI you want to update
        OnPropertyChanged("PROPERTYNAME");
    }

Now that'll trigger for any property changed and gets repeated if you just update everything on each property name that was changed. You can customize how it behaves but the idea is there. You can also access properties in PropertyChangedEventArgs to what properties are being changed.

