WPF组件查找

前言

有这么个需求我们有很多相同的组件,我们要获取到组件的状态,这时候我们就需要查找到所有的标记的组件,获取状态。

工具类

建议在匹配的时候使用Tag,因为Name不能重复。

同时这也能在列表中使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace ZUtils
{
public class ZViewFinder
{
/// <summary>
/// 获取第一个找到的子元素
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parent"></param>
/// <param name="tag"></param>
/// <returns></returns>
public static T FindChild<T>(DependencyObject parent, string tag) where T : DependencyObject
{
if (parent == null)
{
return null;
}

T foundChild = null;

int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject cdo = VisualTreeHelper.GetChild(parent, i);
if (cdo != null)
{
FrameworkElement child = cdo as FrameworkElement;
if (string.IsNullOrEmpty(tag))
{
if (child is T)
{
foundChild = (T)cdo;
break;
}
else
{
foundChild = FindChild<T>(cdo, tag);
}
}
else
{
if (child is T && child.Tag.ToString() == tag)
{
foundChild = (T)cdo;
break;
}
else
{
foundChild = FindChild<T>(cdo, tag);
}
}
}
}

return foundChild;
}

/// <summary>
/// 获取所有的子元素(支持多层)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="parent"></param>
/// <param name="tag"></param>
/// <returns></returns>
public static List<T> FindChilds<T>(DependencyObject parent, string tag) where T : DependencyObject
{
List<T> list = new List<T>();
if (parent == null)
{
return list;
}

int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
DependencyObject cdo = VisualTreeHelper.GetChild(parent, i);
if (cdo != null)
{
FrameworkElement child = cdo as FrameworkElement;
if (child != null)
{
if (child is T)
{
if (string.IsNullOrEmpty(tag))
{
list.Add(child as T);
}
else if (child.Tag.ToString() == tag)
{
list.Add(child as T);
}
}
else
{
// 在下一级控件中递归查找
list.AddRange(FindChilds<T>(child, tag));
}
}
}
}

return list;
}

/// <summary>
/// 查找父元素
/// </summary>
/// <typeparam name="T">
/// </typeparam>
/// <param name="obj">
/// </param>
/// <param name="name">
/// </param>
/// <returns>
/// </returns>
public static T FindParent<T>(DependencyObject depobj) where T : DependencyObject
{
DependencyObject dobj = VisualTreeHelper.GetParent(depobj);
if (dobj != null)
{
if (dobj is T)
{
return (T)dobj;
}
else
{
dobj = FindParent<T>(dobj);
if (dobj != null && dobj is T)
{
return (T)dobj;
}
}
}
return null;
}
}
}

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<UniformGrid
Name="menuParent"
Margin="16,10,16,10"
Columns="1">
<StackPanel Orientation="Horizontal">
<CheckBox
Click="menuItemClick"
Content="教学平台"
IsChecked="True"
Style="{StaticResource ZCheckBoxStyle}"
Tag="menuItem" />
</StackPanel>
<StackPanel Margin="30,0,0,0" Orientation="Horizontal">
<CheckBox
Click="menuItemClick"
Content="个人空间"
IsChecked="True"
Style="{StaticResource ZCheckBoxStyle}"
Tag="menuItem" />
<CheckBox
Margin="20,0,0,0"
Click="menuItemClick"
Content="作业讲评"
IsChecked="True"
Style="{StaticResource ZCheckBoxStyle}"
Tag="menuItem" />
</StackPanel>
</UniformGrid>

C#

1
2
3
4
5
6
7
8
9
private void menuItemClick(object sender, RoutedEventArgs e)
{
List<CheckBox> allMenu = ZViewFinder.FindChilds<CheckBox>(menuParent, "menuItem");
for (int i = 0; i < allMenu.Count; i++)
{
CheckBox cb = allMenu[i];
Console.WriteLine(cb.Content + ":" + cb.IsChecked);
}
}