【问题标题】:Me.Controls does not find all controls on the formMe.Controls 没有找到表单上的所有控件
【发布时间】:2021-09-26 00:44:19
【问题描述】:

我有一个表单,它包含一个搜索词列表,并为每个结果集创建一个组合框。这些框是在运行时创建的,它们都是单独命名的,并且都直接在表单上,​​没有一个在面板或任何子控件中。

我想在每次完成新搜索时删除以前的搜索组合框。我做了以下子删除所有组合框

        For Each c As Control In Me.Controls
        If c.GetType Is GetType(ComboBox) Then 
            Me.Controls.Remove(c)
            c.Dispose()
        End If
    Next c

但由于某种神秘的原因,表单并没有看到之前搜索创建的所有组合框。如果我创建 3 个框,它将看到第一个和第三个,但看不到第二个。如果我再次运行 sub,它将看到第二个并在那个时候捕获它。所以我需要运行 sub 两次才能真正清除所有创建的组合框。我检查了控件集合,它似乎总是比上一次搜索中创建的组合框的实际数量少 1

知道为什么它总是留下一个组合框,我需要再次清除它们以摆脱它吗?

【问题讨论】:

  • 原因并不神秘,您在 Control 集合上使用 For Each,然后处理集合中的项目,这将修改您正在迭代的集合,所以您将处理一半的控件。使用向后的For 循环,或创建这些控件的列表并遍历这个新列表。或者使用转发For 循环并在(0) 处处理。 -- 释放控件时,控件集合会发生变化,因为释放控件也会将其从集合中删除。顺便说一句,你应该有For Each c As Control In Me.Controls.OfType(Of ComboBox)
  • 请注意@Jimi 的评论,如果您在枚举过程中修改集合,.NET 通常会失败并出现错误。

标签: vb.net controls


【解决方案1】:

除了 Jimi 在 cmets 中所说的,我建议你使用这个:

For Each cmbx In Controls.OfType(Of ComboBox)().ToArray()
    cmbx.Dispose()
Next

OfType 首先进行过滤,然后ToArray 创建一个可以循环的数组,因此您不会同时枚举和修改集合。删除和释放控件没有意义,因为释放会隐式删除它们。

【讨论】:

  • 不错的提示。我要编辑我所有的向后 For..Next 循环
  • @DavidWilson,向后的For...Next 效率更高,因为它只循环一次。这里提供的代码先枚举原始集合得到数组,然后再枚举数组。除非您处理的是一个非常大的集合,否则差异将可以忽略不计,而且在我看来,这段代码更简洁。
  • 抱歉 - 请阅读我的上一条评论 - 没有任何负面含义 - 我认为这是一个很好的提示。
猜你喜欢
  • 1970-01-01
  • 2021-03-02
  • 1970-01-01
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
相关资源
最近更新 更多