为什么不删除所有元素?
代码:
$AAD = New-Object system.Windows.Forms.CheckBox
$AAD.Name = 'AAD'
$AAD.text = 'AAD'
$AAD.Checked = $true
$AAD.AutoSize = $true
$AAD.width = 47
$AAD.height = 30
$AAD.enabled = $true
$AAD.location = New-Object System.Drawing.Point(12, 76)
$AAD.Font = New-Object System.Drawing.Font('Microsoft Sans Serif', 10)
$AD = New-Object system.Windows.Forms.CheckBox
$AD.Name = 'AD'
$AD.text = 'AD'
$AD.Checked = $true
$AD.AutoSize = $true
$AD.width = 45
$AD.height = 20
$AD.location = New-Object System.Drawing.Point(64, 76)
$AD.Font = New-Object System.Drawing.Font('Microsoft Sans Serif', 10)
$array = @('AAD', 'AD')
$Form.Controls | where { $array -contains $_.Name } | foreach { $Form.Controls.RemoveByKey($_.Name) }
如果我记录它找到的元素的名称,它会记录这一点(所以它确实找到了两者,但不会删除它们):
AAD
AD
2条答案
按热度按时间rekjcdws1#
我无法解释为什么它无法删除其中一个控件,但我可以为您提供一种更强大的方法,使用
.Remove
而不是.RemoveByKey
不会有这样的问题:关于Jimi's的有用评论:
保留一半控件的原因是在
foreach
循环中删除元素会修改您正在迭代的集合。反向for循环是常见的对策之一--通常,您应该处理不再需要的控件,而不是删除它们。Controls.Remove()
不会释放任何东西(不过,在.NET 5+中,这种行为有些不同)。在迭代集合的同时修改集合可以解释OP的问题,而反向
for
循环的解决方案也可以解决这个问题。我个人仍然坚持使用这个答案中显示的前面的方法,使用.Find
和.Remove
。vfh0ocws2#
添加到Santiago's helpful answer:
.RemoveByKey()
)一个集合($Form.Controls
)*,而它正在被枚举 *。*通常情况下,应该报告 * 错误:
Collection was modified; enumeration operation may not execute.
[1].RemoveByKey()
后,**你的管道 * 会安静地中止 *,这可能是一个 bug -请参阅GitHub issue #20181。$Form.Controls
包含在@(...)
中,数组子表达式运算符,它创建集合的 * 静态副本 *(作为[object[]]
数组),然后将其枚举与$Form.Controls
集合的修改隔离开来:[1]引发此错误的简单方法:
$l = [System.Collections.Generic.List[string]] @('one', 'two'); foreach ($e in $l) { $l.Remove($e) }