Skip to content

Commit da0415e

Browse files
Merge pull request #101 from atc-net/bugfix/VisualTreeHelperEx-GetChild
feat: Fix bug in GetChild method and add FindChild and FindParent
2 parents 19a8b31 + d4a4640 commit da0415e

File tree

1 file changed

+60
-16
lines changed

1 file changed

+60
-16
lines changed

src/Atc.Wpf/Helpers/VisualTreeHelperEx.cs

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,81 @@
1-
#pragma warning disable CS0162 // Unreachable code detected
21
namespace Atc.Wpf.Helpers;
32

3+
/// <summary>
4+
/// Provides extended methods for working with the visual tree in WPF applications.
5+
/// </summary>
46
[SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "OK.")]
57
public static class VisualTreeHelperEx
68
{
7-
public static T? GetParent<T>(DependencyObject child)
9+
/// <summary>
10+
/// Finds and returns the first parent object of the specified type T in the visual tree.
11+
/// </summary>
12+
/// <typeparam name="T">The type of the parent to find.</typeparam>
13+
/// <param name="control">The starting dependency object to search up from.</param>
14+
/// <returns>The first parent object of type T found in the visual tree, or null if no such parent exists.</returns>
15+
public static T? GetParent<T>(
16+
DependencyObject control)
817
where T : DependencyObject
9-
{
10-
var parent = VisualTreeHelper.GetParent(child);
18+
=> FindParent<T>(control);
19+
20+
/// <summary>
21+
/// Searches for and returns the first child object of the specified type T within the visual tree.
22+
/// </summary>
23+
/// <typeparam name="T">The type of the child to find.</typeparam>
24+
/// <param name="control">The parent dependency object to search down from.</param>
25+
/// <returns>The first child of type T found within the visual tree, or null if no such child exists.</returns>
26+
public static T? GetChild<T>(
27+
DependencyObject control)
28+
where T : DependencyObject
29+
=> FindChild<T>(control);
1130

12-
return parent switch
31+
/// <summary>
32+
/// Recursively finds the first parent of the specified type T in the visual tree.
33+
/// </summary>
34+
/// <typeparam name="T">The type of the parent to find.</typeparam>
35+
/// <param name="control">The starting point dependency object to search up from.</param>
36+
/// <returns>The first parent object of type T in the visual tree, or null if no such parent is found.</returns>
37+
public static T? FindParent<T>(
38+
DependencyObject control)
39+
where T : DependencyObject
40+
{
41+
var parent = VisualTreeHelper.GetParent(control);
42+
while (parent is not null)
1343
{
14-
null => null,
15-
T tParent => tParent,
16-
_ => GetParent<T>(parent),
17-
};
44+
if (parent is T tParent)
45+
{
46+
return tParent;
47+
}
48+
49+
parent = VisualTreeHelper.GetParent(parent);
50+
}
51+
52+
return null;
1853
}
1954

20-
[SuppressMessage("Major Bug", "S1751:Loops with at most one iteration should be refactored", Justification = "OK.")]
21-
public static T? GetChild<T>(DependencyObject control)
55+
/// <summary>
56+
/// Recursively searches for and returns the first child of the specified type T within the visual tree.
57+
/// </summary>
58+
/// <typeparam name="T">The type of the child to find.</typeparam>
59+
/// <param name="control">The parent dependency object to search down from.</param>
60+
/// <returns>The first child of type T, or null if no such child is found.</returns>
61+
public static T? FindChild<T>(
62+
DependencyObject control)
2263
where T : DependencyObject
2364
{
2465
var childNumber = VisualTreeHelper.GetChildrenCount(control);
2566
for (var i = 0; i < childNumber; i++)
2667
{
2768
var child = VisualTreeHelper.GetChild(control, i);
69+
if (child is T tChild)
70+
{
71+
return tChild;
72+
}
2873

29-
return child switch
74+
var result = FindChild<T>(child);
75+
if (result is not null)
3076
{
31-
null => null,
32-
T tChild => tChild,
33-
_ => GetChild<T>(child),
34-
};
77+
return result;
78+
}
3579
}
3680

3781
return null;

0 commit comments

Comments
 (0)