我正在寻找一种方法,通过它们的类型在窗口上找到所有控件,
例如:找到所有的文本框,找到所有实现特定界面的控件等。
我正在寻找一种方法,通过它们的类型在窗口上找到所有控件,
例如:找到所有的文本框,找到所有实现特定界面的控件等。
当前回答
对于这个和更多的用例,你可以添加流动扩展方法到你的库:
public static List<DependencyObject> FindAllChildren(this DependencyObject dpo, Predicate<DependencyObject> predicate)
{
var results = new List<DependencyObject>();
if (predicate == null)
return results;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dpo); i++)
{
var child = VisualTreeHelper.GetChild(dpo, i);
if (predicate(child))
results.Add(child);
var subChildren = child.FindAllChildren(predicate);
results.AddRange(subChildren);
}
return results;
}
举个例子:
var children = dpObject.FindAllChildren(child => child is TextBox);
其他回答
我的c++ /CLI版本
template < class T, class U >
bool Isinst(U u)
{
return dynamic_cast< T >(u) != nullptr;
}
template <typename T>
T FindVisualChildByType(Windows::UI::Xaml::DependencyObject^ element, Platform::String^ name)
{
if (Isinst<T>(element) && dynamic_cast<Windows::UI::Xaml::FrameworkElement^>(element)->Name == name)
{
return dynamic_cast<T>(element);
}
int childcount = Windows::UI::Xaml::Media::VisualTreeHelper::GetChildrenCount(element);
for (int i = 0; i < childcount; ++i)
{
auto childElement = FindVisualChildByType<T>(Windows::UI::Xaml::Media::VisualTreeHelper::GetChild(element, i), name);
if (childElement != nullptr)
{
return childElement;
}
}
return nullptr;
};
我发现没有Visual Tree Helpers更容易:
foreach (UIElement element in MainWindow.Children) {
if (element is TextBox) {
if ((element as TextBox).Text != "")
{
//Do something
}
}
};
这是最简单的方法:
IEnumerable<myType> collection = control.Children.OfType<myType>();
其中控件是窗口的根元素。
编辑-正如评论中指出的那样。这只是一个层次的深度。查看一个更深入的选项的公认答案。
我根据@Mathias Lykkegaard Lorenzen的建议改编了@Bryce Kahle的回答,并使用了LogicalTreeHelper。
看起来还行。;)
public static IEnumerable<T> FindLogicalChildren<T> ( DependencyObject depObj ) where T : DependencyObject
{
if( depObj != null )
{
foreach( object rawChild in LogicalTreeHelper.GetChildren( depObj ) )
{
if( rawChild is DependencyObject )
{
DependencyObject child = (DependencyObject)rawChild;
if( child is T )
{
yield return (T)child;
}
foreach( T childOfChild in FindLogicalChildren<T>( child ) )
{
yield return childOfChild;
}
}
}
}
}
(它仍然不会检查@Benjamin Berry和@David R分别提到的组框中的选项卡控件或网格。) (也遵循@noonand的建议&删除多余的子!= null)
这应该可以达到目的:
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
}