【问题标题】:How do I iterate through all the objects in a container?如何遍历容器中的所有对象?
【发布时间】:2013-11-04 16:33:17
【问题描述】:

如果我的面板中包含未知数量的标签,我该如何浏览所有标签并更改其中的 .text 值?我尝试过这样的事情:

for each x as label in mypanel
   x.text = "whatever"
next

但我收到一个错误,即 mypanel 不是集合。

标签是 mypanel 的子标签。

【问题讨论】:

  • mypanel.Controls - 这是为您阅读文档的委员会带给您的。
  • 感谢您的信息。虽然我很欣赏这种讽刺,但该链接确实无助于回答这个问题。我知道对象有控件,但问题是我如何遍历它们。
  • 这是允许您迭代它们的实际属性。事实上,您接受的答案使用它。

标签: arrays vb.net object collections


【解决方案1】:

win 表格试试:

for each x as Control in mypanel.Controls
   if TypeOf x Is Label Then
     CType(x, Label).text = "whatever"
   end if
next

【讨论】:

  • 谢谢,但我不想问它是什么类型的控件,因为我可能不知道并且我不想询问每种类型的控件。我可能拥有的不仅仅是标签。
【解决方案2】:

取决于Panel 的类型。 WinForms? WPF?错误是对的,Panel 不是集合。它只是一个对象。但它的一个属性可能是一个集合。

mypanel.Controls 用于 WinForms,或mypanel.Children 用于 WPF。如果层次结构多于直接子级,那么您可能需要进一步递归到该层次结构。

【讨论】:

    【解决方案3】:
    For Each lbl As Label in myPanel.Controls
         lbl.Text = "whatever"
    Next
    

    这是假设 myPanel 上的所有内容都是标签。如果还有其他控件,则必须测试它们是否为标签:

    For Each ctl as Control in myPanel.Controls
         If Ctl.GetType = Label.GetType Then
            CType(ctl, Label).text = "whatever"
         End if
    Next
    

    【讨论】:

    • 根据你的VB版本,你也可以For Each ctl in myPanel.Controls(Of Label),只获取标签控件。
    【解决方案4】:

    遍历面板中的所有控件,然后判断每个控件是否为Label,如下所示:

    For Each theControl As Control In myPanel.Controls
        If TypeOf theControl Is Label Then
            ' Change the text here
            TryCast(theControl, Label).Text = "whatever"
        End If
    Next
    

    更新:

    要考虑面板中的子控件,请执行以下操作:

    Dim listOfLabels As New List(Of Control)
    
    Public Sub GetAllLabelsIn(container As Control)
        For Each theControl As Control In container.Controls
            If TypeOf theControl Is Label Then    
                listOfLabels.Add(theControl)
    
                If theControl.Controls.Count > 0 Then
                    GetAllLabelsIn(theControl)
                End If
            End If
        Next
    End Sub
    

    现在你可以这样称呼它:

    listOfLabels = new List(Of Control)
    
    GetAllLabelsIn(myPanel)
    
    For Each theControl As Control In listOfLabels
        If TypeOf theControl Is Label Then
            ' Change the text here
            TryCast(theControl, Label).Text = "whatever"
        End If
    Next
    

    【讨论】:

      【解决方案5】:

      您首先只能选择Labels。这也会返回容器内容器内的标签等......

      ' Inside a module
      <Extension()> _
      Public Function ChildControls(Of T As Control)(ByVal parent As Control) As List(Of T)
          Dim result As New ArrayList()
          For Each ctrl As Control In parent.Controls
              If TypeOf ctrl Is T Then result.Add(ctrl)
              result.AddRange(ChildControls(Of T)(ctrl))
          Next
          Return result.ToArray().Select(Of T)(Function(arg1) CType(arg1, T)).ToList()
      End Function
      

      用法:

      For Each myLabel as Label in myPanel.ChildControls(Of Label)
          myLabel.Text = "I'm a label!"
      Next
      

      【讨论】:

      • 你能解释一下吗?我已经可靠地使用了这种方法一段时间了。
      • @JohnSaunders 我刚刚将ArrayList 替换为List(of Control),并在一个包含1024 个标签的3 层容器内的表单上测试了这两种方法。两种方法都在 0 毫秒内完成。不值得更新我的答案,因为它一开始就很好......除非你有其他原因而不是性能?
      • 是的,ArrayList 已过时。
      猜你喜欢
      • 2012-08-08
      • 2016-09-24
      • 1970-01-01
      • 2012-05-17
      • 2011-11-04
      • 2014-10-07
      • 1970-01-01
      • 2016-11-18
      • 1970-01-01
      相关资源
      最近更新 更多