我想动态地将信息分配给" Add_Click"在powershell中的GUI按钮上的事件。
所以概述 - 我正在制作一个GUI工具,它可以加载一些用于定制"修复"对于人们的PC。每个按钮都是从脚本加载的,每个脚本都包含用于信息的变量,例如按钮名称,按钮图标,以及执行脚本要执行的任何操作的函数。
因此,根据下面的示例,我发现问题在于我分配Add_Click事件。我很抱歉不确定如何更好地解释,但它似乎没有扩展$ script变量,它会将add_click保存为变量,这样当我运行程序时,所有按钮都使用最后存储的内容在变量$ script中(所以所有按钮看起来都不一样,但运行相同的脚本)。
我希望能够做的是让每个按钮使用Add_Click来运行在" Foreach"中分配Add_Click时存储在$ script中的任何脚本。循环。
示例脚本:
#Button Container (Array to store all the Buttons)
$ComputerActionButtons = @()
#Get all the script files that we will load as buttons
$buttonsFileArray = Get-ChildItem "$dir\Addin\ " | Select -ExpandProperty Name
#Load Buttons
$ButtonTempCount = 1
Foreach ($script in $buttonsFileArray){
. $dir\Addin\$script
Write-Host "Loading Button: $ButtonName"
# Generate button
$TempButton = New-Object System.Windows.Forms.Button
$TempButton.Location = New-Object System.Drawing.Size(140,20)
$TempButton.Size = New-Object System.Drawing.Size(100,100)
$TempButton.Text = "$ButtonName"
$TempButton.Image = $ButtonIcon
$TempButton.TextImageRelation = "ImageAboveText"
$TempButton.Add_Click({& $dir\Addin\$script})
$ComputerActionButtons += $TempButton
}
#Add Buttons to panel
$CAButtonLoc = 20
Foreach ($button in $ComputerActionButtons){
$button.Location = New-Object System.Drawing.Size(50,$CAButtonLoc)
$ComputerActionsPanel.Controls.Add($button)
$CAButtonLoc = $CAButtonLoc + 120
}
我一直在研究变量,发现你可以做一个New-Variable和Get-Variable命令来动态设置和获取变量名,但由于原始问题,使用它似乎没有帮助。
我希望我已经解释得这么好,如果我能提供更多信息,请告诉我。
谢谢,
亚当
答案 0 :(得分:3)
您需要在分配时在$script
值上创建一个闭包,而不是在运行时依赖$script
的值。
幸运的是,所有ScriptBlock
都支持GetNewClosure()
method。
foreach($i in 1..3){
$blocks += {echo $i}.GetNewClosure()
}
$blocks |Foreach-Object {$_.Invoke()}
产生:
1
2
3
与
相反foreach($i in 1..3){
$blocks += {echo $i}
}
$blocks |Foreach-Object {$_.Invoke()}
产生:
3
3
3
GetNewClosure()
做的是它“捕获”当时ScriptBlock中引用的变量并将其绑定到scriptblock的本地范围。
这样原始的$i
变量(或$script
就此而言)被“隐藏”在与$i
具有相同值的$i
变量下方过去有 - 即在GetNewClosure()
被称为
答案 1 :(得分:2)
不使用创建新动态模块的GetNewClosure
,而是将本地范围变量捕获到它并将ScriptBlock
绑定到该模块,因此实际上您将无法访问未在全局范围内定义的任何函数,您可以在按钮本身中存储任何按钮特定数据。 Control
基类具有Tag
属性,您可以在其中存储所需的任何数据。
$TempButton.Tag=@{Script=$script}
$TempButton.Add_Click({param($Sender) & "$dir\Addin\$($Sender.Tag.Script)"})