Powershell:当事件处理程序在 for 循环内时,复选框更改事件不会给出有效结果

Powershell : When event handler is inside for loop, Checkbox change event does not give valid result

我创建了一组复选框。我可以分别为每个复选框创建一个事件处理程序,但因为这将是冗长的代码,所以我想如果我可以使用循环创建它们。当事件处理程序写在循环内时,事件正在处理,但显示的结果是错误的,即 -> 当我 select 我选中事件处理框时,但 $checkBox_Charts[$i].Checked 总是返回 False 该框是选中还是未选中。

编辑 1:

代码:

function whichCharts(){
    Write-Host "CP1: in whichCharts"
    foreach ($key_chart in $charts.Keys){
        Write-Host $charts[$key_chart]
    }
}

function checkbox_test{
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

# Set the size of your form
$Form = New-Object System.Windows.Forms.Form
$Form.width = 1000
$Form.height = 600
$Form.Text = ”My First Form with a working checkbox”

# Set the font of the text to be used within the form
$Font = New-Object System.Drawing.Font("Times New Roman",12)
$Form.Font = $Font



$charts = @("x","y","z")

$checkBox_Charts =[System.Windows.Forms.checkbox[]]::new(3)

$index_checkBox_Charts=0
for ($i=0;$i -lt $charts.Count; $i++){
$CheckBox = new-object System.Windows.Forms.checkbox
    $height = (60*$i)+20
    $CheckBox.Location = new-object System.Drawing.Size(100,$height)
$CheckBox.Size = '150,50'
$CheckBox.Text = $charts[$i]
$CheckBox.Checked = $false
$checkBox_Charts[$i] = $CheckBox

}



# Add an OK button
$OKButton = new-object System.Windows.Forms.Button
$OKButton.Location = '50,500'
$OKButton.Size = '100,40'
$OKButton.Text = "OK"
$OKButton.DialogResult=[System.Windows.Forms.DialogResult]::OK

#Add a cancel button
$CancelButton = new-object System.Windows.Forms.Button
$CancelButton.Location = '255,100'
$CancelButton.Size = '100,40'
$CancelButton.Text = "Cancel"
$CancelButton.DialogResult=[System.Windows.Forms.DialogResult]::Cancel

# Create a group that will contain your radio buttons
$MyGroupBox = New-Object System.Windows.Forms.GroupBox
$MyGroupBox.Location = '40,30'
$MyGroupBox.size = '800,400'
$MyGroupBox.text = "Do you like Cheese?"

# Add all the GroupBox controls on one line
$MyGroupBox.Controls.AddRange(@($checkBox_Charts))

$Form.Controls.AddRange(@($MyGroupBox,$OKButton,$CancelButton))
###########  This is the important piece ##############
#                                                     #
# Do something when the state of the checkbox changes #
#######################################################

for($i=0; $i -lt 2; $i++){
    $checkBox_Charts[$i].Add_CheckStateChanged({
    Write-Host "CP2: in Add_CheckStateChanged " + $checkBox_Charts[$i].Checked
    Write-Host $checkBox_Charts[$i]
    Write-Host $i})

}



# Activate the form
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog() 
}



#Call the function
checkbox_test

CheckStateChanged 事件的脚本块中,变量 $i 未知。要使它的值在那里可用,您必须将它存储在复选框可以读取的 属性 中。最好的地方是复选框自己的 Tag 属性.

在您的代码中,像这样创建复选框:

$charts = "x","y","z"   # no need to surround this with @()

$checkBox_Charts = [System.Windows.Forms.checkbox[]]::new($charts.Count)
for ($i = 0; $i -lt $charts.Count; $i++){
    $CheckBox = new-object System.Windows.Forms.checkbox
    $height = (60*$i)+20
    $CheckBox.Location = new-object System.Drawing.Size(100,$height)
    $CheckBox.Size = '150,50'
    $CheckBox.Text = $charts[$i]
    $CheckBox.Checked = $false
    # save the index $i in the Tag property of the checkbox itself
    $CheckBox.Tag = $i
    $CheckBox.Add_CheckStateChanged({
        # inside this scriptblock, the variable $i is unknown
        # so we use the index value stored in the Tag property earlier
        Write-Host "CP2: in Add_CheckStateChanged $($this.Checked)"
        Write-Host "CheckBox index: $($this.Tag)"
        Write-Host $checkBox_Charts[$this.Tag]
        Write-Host
    })
    $checkBox_Charts[$i] = $CheckBox
}

然后删除这里的代码:

###########  This is the important piece ##############
#                                                     #
# Do something when the state of the checkbox changes #
#######################################################

for($i=0; $i -lt 2; $i++){
    $checkBox_Charts[$i].Add_CheckStateChanged({
    Write-Host "CP2: in Add_CheckStateChanged " + $checkBox_Charts[$i].Checked
    Write-Host $checkBox_Charts[$i]
    Write-Host $i})

}

因为这一切都是在之前创建复选框时完成的(并且不会像您注意到的那样工作)


作为旁注:

  • 更改此 obsolete/deprecated 代码:

    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    

    进入

    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing

  • straighten the curly quotes you have in $Form.Text = ”My First Form with a working checkbox” to become $Form.Text = "My First Form with a working checkbox".
    They won't hurt you in this case, but using curly quotes in code can lead to numerous weird problems. Never use them in code.

在控件的事件处理程序中,$this 自动变量指的是控件本身