I have some few cases in my WPF application that requires me to find a specific type of user control in a given user control. For example I'm having the following method that already works nicely:
public static System.Windows.Controls.CheckBox FindChildCheckBox(DependencyObject d)
{
try
{
System.Windows.Controls.CheckBox chkBox = d as System.Windows.Controls.CheckBox;
if (d != null && chkBox == null)
{
int count = System.Windows.Media.VisualTreeHelper.GetChildrenCount(d);
for (int i = 0; i < count; i++)
{
chkBox = FindChildCheckBox(System.Windows.Media.VisualTreeHelper.GetChild(d, i));
if (chkBox != null)
break;
}
}
return chkBox;
}
catch
{
return null;
}
}
This method will help me to find a CheckBox in a given ListViewItem which allows me to check/uncheck the said CheckBox more conveniently.
However, I'd like to have this method more generic like for example:
public static T FindChildUserControl<T>(DependencyObject d)
Unfortunately I do not see how I can get this work. Can someone please help?
You need to replace CheckBox
with T
and add a generic restraint (where
) to the type argument.
For example I'm having the following method that already works nicely
Which is odd, as far as I can tell it would only work on nested CheckBoxes. This should on any combination of controls:
public static T FindChild<T>(DependencyObject d) where T : DependencyObject
{
if (d is T)
return (T)d;
int count = System.Windows.Media.VisualTreeHelper.GetChildrenCount(d);
for (int i = 0; i < count; i++)
{
DependencyObject child = FindChild<T>(System.Windows.Media.VisualTreeHelper.GetChild(d, i));
if (child != null)
return (T)child;
}
return null;
}
Usage:
CheckBox check = FindChild<CheckBox>(parent);
To get all children of a certain type, this should work nicely:
public static IEnumerable<T> FindChildren<T>(DependencyObject d) where T : DependencyObject
{
if (d is T)
yield return (T)d;
int count = System.Windows.Media.VisualTreeHelper.GetChildrenCount(d);
for (int i = 0; i < count; i++)
{
foreach (T child in FindChildren<T>(System.Windows.Media.VisualTreeHelper.GetChild(d, i)))
yield return child;
}
}
Usage:
foreach(CheckBox c in FindChildren<CheckBox>(parent))
This method will help me to find a CheckBox in a given ListViewItem which allows me to check/uncheck the said CheckBox more conveniently.
You should use MVVM instead. Walking down the VisualTree is a really hacky workaround.