Suppose you have the following scenario you have two templated UserControl:

  • UCContainer - is a graphical container for other controls, it can be used to contain different kinds of controls, it can be skinned using a template that will be changed by the user/graphic designer. You cannot do any assumptions on the template.
  • UCDetail - is a detail control contained in a UCContainer.

Given an instance of UCDetail, we want to access and modify property of the UCContainer that contains it. if You are lucky the Parent property or the VisualTreeHelper.GetParent() function can give you a reference to the UCContainer control itself. But more often they will give you a reference to a container control defined inside the UCContainer template (usually a StackPanel or a Grid).

I’m not willing to go deep into concepts like the WPF Visual and Logical tree, you have tons of resources and books to look at for that.

The only viable way I’ve found so far to get the ‘logical’ parent of the control is to use a recursion and look if the type of the parent object returned by and UIElement matches the type of the object that I consider his ‘logical’ parent, Here’s the code that does the trick:

public static partial class Extensions
{
   public static T FindAncestor<T>(DependencyObject obj) where T : DependencyObject
   {
      while (obj != null)
      {
         T o = obj as T;
         if (o != null)
            return o;
         obj = VisualTreeHelper.GetParent(obj);
      }
      return null;
   }
 
   public static T FindAncestor<T>(this UIElement obj) where T : UIElement
   {
      return FindAncestor<T>((DependencyObject)obj);
   }
 
}

Related Content