【问题标题】:How do I Iterate controls in a windows form app?如何在 Windows 窗体应用程序中迭代控件?
【发布时间】:2009-09-24 17:02:34
【问题描述】:

所以这是一个愚蠢的问题。我在我编写的应用程序的选项对话框中添加了一堆文本框。它们被命名为 textbox1 - textbox12。有没有办法以编程方式访问名称?我只想在 for 循环中迭代它们。现在我正在单独访问每一个(不寒而栗!)。我知道这是错误的方式。什么是正确的方法?什么是简单的方法?

谢谢

【问题讨论】:

    标签: c# .net winforms


    【解决方案1】:
    foreach (Control c in this.Controls)
    {
        if (c is TextBox)
        {
            // your logic here
        }
    }
    

    如果它们具有不同的功能,那么您可能需要进行更多检查,而不仅仅是确定它们是正确的类型。当然,这假设您已导入 System.Windows.Forms 命名空间。

    【讨论】:

      【解决方案2】:

      Controls 集合允许您按名称访问项目,因此您可以这样做:

      var textboxes = Enumerable.Range(1, 12).Select(i => String.Format("textbox{0}", i)).Select(name => (TextBox)this.Controls[name]);
      

      这将避免枚举集合中的每个控件,尽管它很脆弱,因为它取决于所使用的命名约定。

      您也可以只使用 OfType 查询方法:

      var textboxes = this.Controls.OfType<TextBox>();
      

      【讨论】:

      • +1 for var textboxes = this.Controls.OfType&lt;TextBox&gt;(); ... 这正是我所说的寻找自己。 :)
      • 太棒了。为 OfType 方法 +1
      【解决方案3】:

      我个人更喜欢以编程方式创建控件,然后将它们放入集合中。即

      IList<TextBox> textBoxes = new List<TextBox>();
      
      …
      
          for (int i = 0; i < 12; i += 1)
          {
              TextBox textBox = new TextBox();
              textBox.Position = new Point(FormMargin, FormMargin + (i * (textBox.Height + TextBoxPadding)));
              this.Controls.Add(textBox);
              this.textBoxes.Add(textBox);
          }
      

      然后您可以遍历文本框以编程方式添加它们。我发现当您需要使用几组不同的文本框时,这会更好地扩展。

      【讨论】:

      • 我知道我需要这样做。这是我从一开始就应该做的。谢谢!!!!
      【解决方案4】:

      您可以编写一个更通用的函数。

      IEnumerable<T> GetChildren<T>(Control owner)
      {
          foreach (Control c in owner.Controls)
          {
              if (c is T)
              {
                  yield return c as T;
              }
          }
      }
      

      这样使用:

      foreach (TextBox tb in GetChildren<TextBox>(optionsControl))
      {
          System.Diagnostics.Trace.WriteLine(tb.Name);
      }
      

      【讨论】:

        【解决方案5】:

        我有一个页面,它通过转发器向页面添加了可变数量的复选框,我需要对它们执行一些操作。我最终编写了这个通用扩展方法,以便将来可以将其用于任何控件。如果您的复选框位于页面上的其他控件中,这也会深入挖掘子控件。

        public static List<TChildType> FindChildrenOfType<TChildType>(this Control currentControl)
            where TChildType : Control
        {
            var childList = new List<TChildType>();
            foreach (Control childControl in currentControl.Controls)
            {
                if (childControl is TChildType)
                {
                    childList.Add((TChildType)childControl);
                }
        
                childList.AddRange(childControl.FindChildrenOfType<TChildType>());
        
            }
            return childList;
        }
        

        在页面中,它是这样使用的:

        var checkedCheckboxes = _myRepeater.FindChildrenOfType<CheckBox>().FindAll(c => c.Checked);
        

        【讨论】:

        • 基于上面的一些例子,用 Control.OfType() 替换我的内部循环会更好,但我不想改变这个例子,直到我有机会测试它。
        • 这似乎是唯一通过使用递归返回嵌套控件(另一个控件内的控件,如 TabControl)的答案。
        猜你喜欢
        • 2020-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多