如何使找到特定类型的子用户控件的方法更通用?

How to make method, that finds sepcific type of child user control, more generic?

我的 WPF 应用程序中有几个案例要求我在给定的用户控件中找到特定类型的用户控件。例如,我有以下已经很好地工作的方法:

    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;
        }
    }

此方法将帮助我在给定的 ListViewItem 中找到 CheckBox,这使我可以更方便地 check/uncheck 所述 CheckBox。

但是,我想让这个方法更通用,例如:

public static T FindChildUserControl<T>(DependencyObject d)

不幸的是,我不知道如何才能完成这项工作。有人可以帮忙吗?

您需要将 CheckBox 替换为 T 并向类型参数添加通用约束 (where)。

For example I'm having the following method that already works nicely

这很奇怪,据我所知它只适用于嵌套的复选框。这应该在任何控件组合上:

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;
}

用法:

CheckBox check = FindChild<CheckBox>(parent);

要获得某种类型的 all children,这应该很有效:

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;
    }
}

用法:

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.

您应该改用 MVVM。沿着 VisualTree 走下去是一个 确实 棘手的解决方法。