FindName method of FrameworkElement class is used to find elements or controls by their Name properties. This article shows how to find controls on a Window by name. FindName method of FrameworkElement class is used to find elements or controls by their Name properties.
WPF SDK continues to use the term "control" to loosely mean any class that represents a visible object in an application, it is important to note that a class does not need to inherit from the Control class to have a visible presence.
This should do the trick
public static IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj == null)
return;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
yield return (T)child;
foreach (T childOfChild in FindVisualChildren<T>(child))
yield return childOfChild;
}
}
then you enumerate over the controls like so
foreach (var tb in FindVisualChildren<TextBlock>(window))
{
// do something with tb here
}
This is the easiest way:
IEnumerable<myType> collection = control.Children.OfType<myType>();
where control is the root element of the window.
EDIT - As pointed out in the comments. This only goes one level deep. See the accepted answer for an option that goes deeper.
I adapted @Bryce Kahle's answer to follow @Mathias Lykkegaard Lorenzen's suggestion and use LogicalTreeHelper
.
Seems to work okay. ;)
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;
}
}
}
}
}
(It still won't check tab controls or Grids inside GroupBoxes as mentioned by @Benjamin Berry & @David R respectively.) (Also followed @noonand's suggestion & removed the redundant child != null)
Use the helper classes VisualTreeHelper
or LogicalTreeHelper
depending on which tree you're interested in. They both provide methods for getting the children of an element (although the syntax differs a little). I often use these classes for finding the first occurrence of a specific type, but you could easily modify it to find all objects of that type:
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;
}
I found that the line, VisualTreeHelper.GetChildrenCount(depObj);
, used in several examples above does not return a non-zero count for GroupBox
es, in particular, where the GroupBox
contains a Grid
, and the Grid
contains children elements. I believe this may be because the GroupBox
is not allowed to contain more than one child, and this is stored in its Content
property. There is no GroupBox.Children
type of property. I am sure I did not do this very efficiently, but I modified the first "FindVisualChildren" example in this chain as follows:
public IEnumerable<T> FindVisualChildren<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj != null)
{
int depObjCount = VisualTreeHelper.GetChildrenCount(depObj);
for (int i = 0; i <depObjCount; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(depObj, i);
if (child != null && child is T)
{
yield return (T)child;
}
if (child is GroupBox)
{
GroupBox gb = child as GroupBox;
Object gpchild = gb.Content;
if (gpchild is T)
{
yield return (T)child;
child = gpchild as T;
}
}
foreach (T childOfChild in FindVisualChildren<T>(child))
{
yield return childOfChild;
}
}
}
}
To get a list of all childs of a specific type you can use:
private static IEnumerable<DependencyObject> FindInVisualTreeDown(DependencyObject obj, Type type)
{
if (obj != null)
{
if (obj.GetType() == type)
{
yield return obj;
}
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
foreach (var child in FindInVisualTreeDown(VisualTreeHelper.GetChild(obj, i), type))
{
if (child != null)
{
yield return child;
}
}
}
}
yield break;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With