如何获取特定类型(按钮/文本框)的Windows窗体表单的所有子控件?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获取特定类型(按钮/文本框)的Windows窗体表单的所有子控件?相关的知识,希望对你有一定的参考价值。

我需要获取x类型的表单上的所有控件。我很确定我曾经使用过这样的代码:

dim ctrls() as Control
ctrls = Me.Controls(GetType(TextBox))

我知道我可以迭代所有控件让孩子们使用递归函数,但是有更简单或更直接的东西,可能如下所示?

Dim Ctrls = From ctrl In Me.Controls Where ctrl.GetType Is Textbox
答案

这是你的另一个选择。我通过创建一个示例应用程序来测试它,然后我将GroupBox和GroupBox放在最初的GroupBox中。在嵌套的GroupBox中,我放了3个TextBox控件和一个按钮。这是我使用的代码(甚至包括你正在寻找的递归)

public IEnumerable<Control> GetAll(Control control,Type type)
{
    var controls = control.Controls.Cast<Control>();

    return controls.SelectMany(ctrl => GetAll(ctrl,type))
                              .Concat(controls)
                              .Where(c => c.GetType() == type);
}

要在表单加载事件中测试它,我想要计算初始GroupBox中的所有控件

private void Form1_Load(object sender, EventArgs e)
{
    var c = GetAll(this,typeof(TextBox));
    MessageBox.Show("Total Controls: " + c.Count());
}

它每次返回正确的计数,所以我认为这将完美适合你正在寻找的:)

另一答案

这是解决方案。

https://stackoverflow.com/a/19224936/1147352

我写了这段代码并只选择了面板,你可以添加更多的开关或ifs。在里面

另一答案
public List<Control> GetAllChildControls(Control Root, Type FilterType = null)
{
    List<Control> AllChilds = new List<Control>();
    foreach (Control ctl in Root.Controls) {
        if (FilterType != null) {
            if (ctl.GetType == FilterType) {
                AllChilds.Add(ctl);
            }
        } else {
            AllChilds.Add(ctl);
        }
        if (ctl.HasChildren) {
            GetAllChildControls(ctl, FilterType);
        }
    }
    return AllChilds;
}
另一答案

这是Control的扩展方法,使用LINQ,作为@PsychoCoder版本的改编:

它需要一个类型列表,它允许您不需要多次调用GetAll来获得您想要的内容。我目前使用它作为重载版本。

public static IEnumerable<Control> GetAll(this Control control, IEnumerable<Type> filteringTypes)
{
    var ctrls = control.Controls.Cast<Control>();

    return ctrls.SelectMany(ctrl => GetAll(ctrl, filteringTypes))
                .Concat(ctrls)
                .Where(ctl => filteringTypes.Any(t => ctl.GetType() == t));
}

用法:

//   The types you want to select
var typeToBeSelected = new List<Type>
{
    typeof(TextBox)
    , typeof(MaskedTextBox)
    , typeof(Button)
};

//    Only one call
var allControls = MyControlThatContainsOtherControls.GetAll(typeToBeSelected);

//    Do something with it
foreach(var ctrl in allControls)
{
    ctrl.Enabled = true;
}
另一答案
   IEnumerable<Control> Ctrls = from Control ctrl in Me.Controls where ctrl is TextBox | ctrl is GroupBox select ctr;

Lambda表达式

IEnumerable<Control> Ctrls = Me.Controls.Cast<Control>().Where(c => c is Button | c is GroupBox);
另一答案

一个干净简单的解决方案(C#):

static class Utilities {
    public static List<T> GetAllControls<T>(this Control container) where T : Control {
        List<T> controls = new List<T>();
        if (container.Controls.Count > 0) {
            controls.AddRange(container.Controls.OfType<T>());
            foreach (Control c in container.Controls) {
                controls.AddRange(c.GetAllControls<T>());
            }
        }

        return controls;
    }
}

获取所有文本框:

List<TextBox> textboxes = myControl.GetAllControls<TextBox>();
另一答案

这是我的Extension方法。这是非常有效和懒惰。

用法:

var checkBoxes = tableLayoutPanel1.FindChildControlsOfType<CheckBox>();

foreach (var checkBox in checkBoxes)
{
    checkBox.Checked = false;
}

代码是:

public static IEnumerable<TControl> FindChildControlsOfType<TControl>(this Control control) where TControl : Control
    {
        foreach (var childControl in control.Controls.Cast<Control>())
        {
            if (childControl.GetType() == typeof(TControl))
            {
                yield return (TControl)childControl;
            }
            else
            {
                foreach (var next in FindChildControlsOfType<TControl>(childControl))
                {
                    yield return next;
                }
            }
        }
    }
另一答案

我从@PsychoCoder修改过。现在可以找到所有控件(包括嵌套)。

public static IEnumerable<T> GetChildrens<T>(Control control)
{
  var type = typeof (T);

  var allControls = GetAllChildrens(control);

  return allControls.Where(c => c.GetType() == type).Cast<T>();
}

private static IEnumerable<Control> GetAllChildrens(Control control)
{
  var controls = control.Controls.Cast<Control>();
  return controls.SelectMany(c => GetAllChildrens(c))
    .Concat(controls);
}
另一答案

这可能有效:

Public Function getControls(Of T)() As List(Of T)
    Dim st As New Stack(Of Control)
    Dim ctl As Control
    Dim li As New List(Of T)

    st.Push(Me)

    While st.Count > 0
        ctl = st.Pop
        For Each c In ctl.Controls
            st.Push(CType(c, Control))
            If c.GetType Is GetType(T) Then
                li.Add(CType(c, T))
            End If
        Next
    End While

    Return li
End Function

我认为获得所有控件的功能只适用于WPF

另一答案

这是经过测试和工作的通用解决方案:

我有一个大量的UpDownNumeric控件,一些在主窗体中,一些在窗体内的groupbox中。我只希望最后选择的一个控件将背景颜色更改为绿色,我首先使用此方法将所有其他控件设置为白色:(也可以扩展为孙子)

    public void setAllUpDnBackColorWhite()
    {
        //To set the numericUpDown background color of the selected control to white: 
        //and then the last selected control will change to green.

        foreach (Control cont in this.Controls)
        {
           if (cont.HasChildren)
            {
                foreach (Control contChild in cont.Controls)
                    if (contChild.GetType() == typeof(NumericUpDown))
                        contChild.BackColor = Color.White;
            }
            if (cont.GetType() == typeof(NumericUpDown))
                cont.BackColor = Color.White;
       }
    }   
另一答案

你可以试试这个:)

    private void ClearControls(Control.ControlCollection c)
    {
        foreach (Control control in c)
        {
            if (control.HasChildren)
            {
                ClearControls(control.Controls);
            }
            else
            {
                if (control is TextBox)
                {
                    TextBox txt = (TextBox)control;
                    txt.Clear();
                }
                if (control is ComboBox)
                {
                    ComboBox cmb = (ComboBox)control;
                    if (cmb.Items.Count > 0)
                        cmb.SelectedIndex = -1;
                }

                if (control is CheckBox)
                {
                    CheckBox chk = (CheckBox)control;
                    chk.Checked = false;
                }

                if (control is RadioButton)
                {
                    RadioButton rdo = (RadioButton)control;
                    rdo.Checked = false;
                }

                if (control is ListBox)
                {
                    ListBox listBox = (ListBox)control;
                    listBox.ClearSelected();
                }
            }
        }
    }
    private void btnClear_Click(object sender, EventArgs e)
    {
        ClearControls((ControlCollection)this.Controls);
    }
另一答案

在C#中(因为

以上是关于如何获取特定类型(按钮/文本框)的Windows窗体表单的所有子控件?的主要内容,如果未能解决你的问题,请参考以下文章

Selenium-针对alert弹窗无法获取,弹出no such alert的解决方法

Windows Store App XAML - 如何获取导航页面的文本框值

获取特定任务栏按钮的上下文菜单文本

如何从文本框中获取特定文本并传输到另一个文本框?

如何从按钮单击事件中获取特定的图片框?

windows窗体创建10个textBox动态这个文本值怎么获取?