Provides static and extension methods for navigating WPF visual and logical trees and finding descendants or ancestors by type and name.
It extends WPF's VisualTreeHelper.GetParent and VisualTreeHelper.GetChild capabilities with optional traversal through ContentElement objects.
Install the package from NuGet:
dotnet add package ExtendedWPFVisualTreeHelperThen import the namespace and use either the extension methods or static helpers:
using EMA.ExtendedWPFVisualTreeHelper;
var button = root.FindChild<Button>("SubmitButton");
var window = button.FindParent<Window>();The supported compatibility baselines are .NET Framework 4.6.2 and the supported LTS .NET Windows targets.
- Use
FindParentmethods to travel up the tree andFindChildmethods to walk down it. - Use either static helpers or extension methods:
- For example:
WpfVisualFinders.FindParent<Window>(node)ornode.FindParent<Window>().
- For example:
- Most searches target a specific type and optionally a name or a regex filter:
- Type can be given at compile time or at runtime using the
ByTypemethods.- For example:
FindParent<MyType>(node)versusFindParentByType(node, typeof(MyType)).
- For example:
- Runtime type searches support classes and interfaces.
- You can target
objectto disable type filtering during a generic search. - Name filtering is enabled by setting the optional
nameargument. - A name can be an exact value or a regular expression. Regex evaluation uses a bounded timeout.
- Use
NameMatchMode.ExactorNameMatchMode.Regexwhen the interpretation must be explicit.ExactOrRegexpreserves the original exact-first behavior.
- Type can be given at compile time or at runtime using the
Finds a child of the specified type by walking down the visual tree from the supplied node. Every branch is explored until a matching child is found.
T? FindChild<T>(DependencyObject? node, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
DependencyObject? FindChildByType(DependencyObject? node, Type? type, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
Finds a child of a specific type by walking down the visual tree from the passed node and through first encountered children only. Search is stopped when a matching item is found or when the most accessible leaf is reached.
T? FindDirectChild<T>(DependencyObject? node, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
DependencyObject? FindDirectChildByType(DependencyObject? node, Type? type, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
Builds an enumerable of all descendants that match the target type and optional name or regex. Every path below the starting node is explored.
IEnumerable<T> FindAllChildren<T>(DependencyObject? node, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
IEnumerable<DependencyObject> FindAllChildrenByType(DependencyObject? node, Type? type, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
Note This method explores and exposes the matching children level-by-level rather than branch-by-branch. Thus, all matching children are exposed, then all matching grandchildren, then all matching grand-grandchildren, etc.
Finds first parent that matches specified type and optional name or regex by walking up the visual tree from the passed node. Returns null after tree top is reached with no result.
T? FindParent<T>(DependencyObject? node, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
DependencyObject? FindParentByType(DependencyObject? node, Type? type, string? name = null, bool allowContentElements = true, NameMatchMode nameMatchMode = NameMatchMode.ExactOrRegex)
Finds the parent at a given depth from the supplied node. Returns null if that level does not exist.
DependencyObject? FindParentByLevel(DependencyObject? node, int level = 1, bool allowContentElements = true)
Note When level defaults to 1, the method gets the immediate parent.
An extension of the VisualTreeHelper.GetParent() method that supports travel through ContentElement objects.
DependencyObject? GetParentExtended(DependencyObject? node)
ContentElement objects—and more specifically their derived FrameworkContentElement counterparts—participate in WPF content and logical trees but cannot be attached directly to the visual tree. They share useful APIs, including naming, with visual-tree objects such as FrameworkElement.
All these reasons make them important nodes to find or travel through while exploring the visual tree, although they are not part of it. As a consequence:
All provided methods allow
ContentElementtraversal by default. Disable this behavior by settingallowContentElements: false.
Some ContentElement examples:
This work is licensed under the MIT License.