WPF User Interface is represented in a way of tree. There are two ways that the complete object tree is conceptualized and can be reported to its public API: as the logical tree and as the visual tree. The Logical tree does not contain the core controls of WPF. For example, the child object of a ContentControl is just represented by Content property. The visual tree includes all the controls that WPF used internally to build the tree system. For example the content of ContentControl is represented by a TextBlock, if the value is string. And again the textblock may composed of a scroll viewer and error adorner, etc.

WPF provides built-in API to traverse the tree, but it is limited. For example if you want to get an element in top of tree by its name or type, you need iterate over the tree by using VisualTreeHelper class. Below, I have provided some useful extensions that will help to get the parent or child in any application.

FindAncestor

Usage

Grid rootGrid = submitButton.FindAncestor<Grid>();

Source

        public static T FindAncestor<T>(this DependencyObject element)
where T : DependencyObject
{
// Try get a parent and check for type.
var parent = VisualTreeHelper.GetParent(element);
if (parent is T)
{
return (T)parent;
}
return FindAncestor<T>(parent);
}

FindDescendant

Usage

Button submitButton = root.FindDescendant<Button>();

Usage

        public static T FindDescendant<T>(this DependencyObject element)
where T : DependencyObject
{
if (element == null) return null;

T foundChild = null;

int childrenCount = VisualTreeHelper.GetChildrenCount(element);
// Iterating through all children.
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(element, i);
// Check whether child is of that type.
T childType = child as T;
if (childType == null)
{
// A recursive call since it is null.
foundChild = FindDescendant<T>(child);

if (foundChild != null) break;
}
else
{
// Child found
foundChild = (T)child;
break;
}
}

return foundChild;
}

VisualTreeExtensions.cs

The class has another overload where the method will accept a string parameter for name. It will return the element of that type with that name.