foreach循环中的匿名clickhandler使用最后一个变量状态

时间:2017-08-18 05:09:50

标签: forms powershell

我想这是一个新手问题。但我没有在网上找到任何东西......

我正在用一个非常简单的gui创建一个小的PowerShell脚本。

这是脚本的相关部分:

foreach ($script in $scripts){
  $btn = New-Object System.Windows.Forms.Button  
  #Text, Location, Size omitted

  #Add clickhandler
  $btn.Add_Click(
    {    
      Write-Host "Clicked on Btn $script"
      Start-Process -FilePath "powershell" -ArgumentList "-command", "`"$script`""
      Write-Host "finished"
      $Form.Close();
    }
  )
  $Form.Controls.Add($btn)
}

显然$scripts包含指向其他PowerShell脚本的路径。 作为一名Java开发人员,我非常天真地怀疑每个点击处理程序是否都有自己对脚本位置的引用($script)。

但是当然,在调用处理程序之前,powershell不会评估$script。因此,每个按钮都会调用我的数组$scripts中的最后一个元素,因为$script将在循环完成后引用$scripts中的最后一个元素。

如何基于循环变量本身在foreach循环内创建单击处理程序?

解决方案

Mathias R. Jessen向我指出了一个有效的解决方案。 .GetNewClosure()呼吁处理程序工作。

工作代码:

foreach ($script in $scripts){
  $btn = New-Object System.Windows.Forms.Button  
  #Text, Location, Size omitted

  #Add clickhandler
  $btn.Add_Click(
    {    
      Write-Host "Clicked on Btn $script"
      Start-Process -FilePath "powershell" -ArgumentList "-command", "`"$script`""
      Write-Host "finished"
      $Form.Close();
    }.GetNewClosure()
  )
  $Form.Controls.Add($btn)
}

1 个答案:

答案 0 :(得分:1)

解决方案

Mathias R. Jessen向我指出了一个有效的解决方案。 .GetNewClosure()调用处理程序工作。

工作代码:

foreach ($script in $scripts){
  $btn = New-Object System.Windows.Forms.Button  
  #Text, Location, Size omitted

  #Add clickhandler
  $btn.Add_Click(
    {    
      Write-Host "Clicked on Btn $script"
      Start-Process -FilePath "powershell" -ArgumentList "-command", "`"$script`""
      Write-Host "finished"
      $Form.Close();
    }.GetNewClosure()
  )
  $Form.Controls.Add($btn)
}