我正在寻找一种方法,通过它们的类型在窗口上找到所有控件,
例如:找到所有的文本框,找到所有实现特定界面的控件等。
我正在寻找一种方法,通过它们的类型在窗口上找到所有控件,
例如:找到所有的文本框,找到所有实现特定界面的控件等。
当前回答
这就是它向上的工作原理
private T FindParent<T>(DependencyObject item, Type StopAt) where T : class
{
if (item is T)
{
return item as T;
}
else
{
DependencyObject _parent = VisualTreeHelper.GetParent(item);
if (_parent == null)
{
return default(T);
}
else
{
Type _type = _parent.GetType();
if (StopAt != null)
{
if ((_type.IsSubclassOf(StopAt) == true) || (_type == StopAt))
{
return null;
}
}
if ((_type.IsSubclassOf(typeof(T)) == true) || (_type == typeof(T)))
{
return _parent as T;
}
else
{
return FindParent<T>(_parent, StopAt);
}
}
}
}
其他回答
使用帮助类VisualTreeHelper或LogicalTreeHelper,这取决于你对哪棵树感兴趣。它们都提供了获取元素的子元素的方法(尽管语法略有不同)。我经常使用这些类来查找特定类型的第一个出现,但你可以很容易地修改它来查找该类型的所有对象:
public static DependencyObject FindInVisualTreeDown(DependencyObject obj, Type type)
{
if (obj != null)
{
if (obj.GetType() == type)
{
return obj;
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
DependencyObject childReturn = FindInVisualTreeDown(VisualTreeHelper.GetChild(obj, i), type);
if (childReturn != null)
{
return childReturn;
}
}
}
return null;
}
我发现没有Visual Tree Helpers更容易:
foreach (UIElement element in MainWindow.Children) {
if (element is TextBox) {
if ((element as TextBox).Text != "")
{
//Do something
}
}
};
这就是它向上的工作原理
private T FindParent<T>(DependencyObject item, Type StopAt) where T : class
{
if (item is T)
{
return item as T;
}
else
{
DependencyObject _parent = VisualTreeHelper.GetParent(item);
if (_parent == null)
{
return default(T);
}
else
{
Type _type = _parent.GetType();
if (StopAt != null)
{
if ((_type.IsSubclassOf(StopAt) == true) || (_type == StopAt))
{
return null;
}
}
if ((_type.IsSubclassOf(typeof(T)) == true) || (_type == typeof(T)))
{
return _parent as T;
}
else
{
return FindParent<T>(_parent, StopAt);
}
}
}
}
这应该可以达到目的:
public static IEnumerable<T> FindVisualChilds<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj == null) yield return (T)Enumerable.Empty<T>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
DependencyObject ithChild = VisualTreeHelper.GetChild(depObj, i);
if (ithChild == null) continue;
if (ithChild is T t) yield return t;
foreach (T childOfChild in FindVisualChilds<T>(ithChild)) yield return childOfChild;
}
}
然后像这样枚举控件
foreach (TextBlock tb in FindVisualChildren<TextBlock>(window))
{
// do something with tb here
}
这是最简单的方法:
IEnumerable<myType> collection = control.Children.OfType<myType>();
其中控件是窗口的根元素。
编辑-正如评论中指出的那样。这只是一个层次的深度。查看一个更深入的选项的公认答案。