i want to get all Controls/UIElements in a window/page. how can i do this? i used this code but is not working and only return one element
private IEnumerable<UIElement> GetUI(UIElement root)
{
yield return root;
if (root is Panel panel)
{
foreach (var item in panel.Children)
{
GetUI(item);
yield return item;
}
}
}
CodePudding user response:
use this way:
var childs = grid.FindChildren();
extensions
public static IEnumerable<FrameworkElement> FindChildren(this FrameworkElement element)
{
Start:
if (element is Panel panel)
{
foreach (UIElement child in panel.Children)
{
if (child is not FrameworkElement current)
{
continue;
}
yield return current;
foreach (FrameworkElement childOfChild in FindChildren(current))
{
yield return childOfChild;
}
}
}
else if (element is ItemsControl itemsControl)
{
foreach (object item in itemsControl.Items)
{
if (item is not FrameworkElement current)
{
continue;
}
yield return current;
foreach (FrameworkElement childOfChild in FindChildren(current))
{
yield return childOfChild;
}
}
}
else if (element is ContentControl contentControl)
{
if (contentControl.Content is FrameworkElement content)
{
yield return content;
element = content;
goto Start;
}
}
else if (element is Border border)
{
if (border.Child is FrameworkElement child)
{
yield return child;
element = child;
goto Start;
}
}
else if (element is ContentPresenter contentPresenter)
{
if (contentPresenter.Content is FrameworkElement content)
{
yield return content;
element = content;
goto Start;
}
}
else if (element is Viewbox viewbox)
{
if (viewbox.Child is FrameworkElement child)
{
yield return child;
element = child;
goto Start;
}
}
else if (element is UserControl userControl)
{
if (userControl.Content is FrameworkElement content)
{
yield return content;
element = content;
goto Start;
}
}
else if (element.GetContentControl() is FrameworkElement containedControl)
{
yield return containedControl;
element = containedControl;
goto Start;
}
}
public static UIElement? GetContentControl(this FrameworkElement element)
{
Type type = element.GetType();
TypeInfo? typeInfo = type.GetTypeInfo();
while (typeInfo is not null)
{
// We need to manually explore the custom attributes this way as the target one
// is not returned by any of the other available GetCustomAttribute<T> APIs.
foreach (CustomAttributeData attribute in typeInfo.CustomAttributes)
{
if (attribute.AttributeType == typeof(ContentPropertyAttribute))
{
string propertyName = (string)attribute.NamedArguments[0].TypedValue.Value;
PropertyInfo? propertyInfo = type.GetProperty(propertyName);
return propertyInfo?.GetValue(element) as UIElement;
}
}
typeInfo = typeInfo.BaseType?.GetTypeInfo();
}
return null;
}
CodePudding user response:
Use the Visual Tree helper class from Microsoft
They even give you an example on how to use it
internal static void FindChildren<T>(List<T> results, DependencyObject startNode)
where T : DependencyObject
{
int count = VisualTreeHelper.GetChildrenCount(startNode);
for (int i = 0; i < count; i )
{
DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
{
T asType = (T)current;
results.Add(asType);
}
FindChildren<T>(results, current);
}
}