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

时间:2018-02-27 09:49:05

标签: c# wpf generics visualtreehelper

我的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,它允许我更方便地检查/取消选中所说的CheckBox。

但是,我希望这种方法更通用,例如:

public static T FindChildUserControl<T>(DependencyObject d)

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

1 个答案:

答案 0 :(得分:2)

您需要将CheckBox替换为T,并在type参数中添加通用限制(where)。

  

例如,我有以下方法已经很好地运作

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

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

要获得特定类型的所有子项,这应该可以正常运行:

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))
  

这个方法可以帮助我在给定的ListViewItem中找到一个CheckBox,它允许我更方便地检查/取消选中所说的CheckBox。

您应该使用MVVM。走下VisualTree是一个真的 hacky解决方法。