Option 1
If your subcontrols are implemented in your own code, a good way is to:
- Create a custom
RoutedEvent
- Send the routed event from the parent whenever you want to inform the subcontrols of something
- Handle the routed event in the subcontrols and respond with the desried behavior (for example expanding if they are drop targets)
You can add parameters to your routed event's EventArgs
to inform subcontrols of the specifics of the change you are informing them about.
Option 2
If you want to affect controls that you don't create and have no control over, you can recursively descend the visual tree using VisualTreeHelper.GetChildrenCount()
and VisualTreeHelper.GetChild()
and make whatever changes you want to the controls you find. This is more powerful than the RoutedEvent method but in many cases does not provide as good an abstraction, leading to code that is harder to maintain in the long run.
Option 3
Use an inherited attached property. Setting the property on the parent will cause the property to propagate down to each descendant, calling your PropertyChangedCallback
each time. In your PropertyChangedCallback
you can make whatever changes you want to the child controls.
This can be better than descending the visual tree recursively because you will also get PropertyChangedCallback
s if new subcontrols are added to your tree. This means that new children that are added later (eg through data binding) will also get the updated features (eg they will also expand if they are drop targets). Another advantage is that inherited properties propagates down the logical tree as well as the visual. A disadvantage is they can be slower than the VisualTreeHelper
technique, and are slightly more code.