I have a PowerShell script that returns a $results
array which can vary in length. I need to create a drop down for each of those results. Since the length of $results
varies, I have the combo box creation in a for loop. However, not all of the combo boxes work; only the last one works.
Here is sample code below. It creates two labels and two combo boxes. ComboBox1 should update Label1 when ComboBox1.selected is changed and ComboBox2 should change Label2. However, the only ComboBox2 changes Label2 but ComboBox1 doesn't update Label1 and writes -1 out of bounds to the console. I'm unsure of how to get it to work for both ComboBoxes.
$form = New-Object System.Windows.Forms.Form
$form.StartPosition = "CenterScreen"
$form.Size = New-Object System.Drawing.Size(500, 300)
$form.Text = "TestForLoop-ComboBoxes"
$ComboBoxArr = @('ex0','ex1','ex3')
$results = @("result 1", "result2")
$x = 0
$y = 0
foreach($result in $results){
$Label = New-Object System.Windows.Forms.Label
$Label.Width = 170
$Label.Height = 20
$Label.Location = New-Object System.Drawing.Point(0, $y)
$Label.Text = "Selected:"
$form.controls.Add($Label)
$ComboBox = New-Object System.Windows.Forms.ComboBox
$ComboBox.Text = ""
$ComboBox.width = 170
$ComboBox.Location = New-Object System.Drawing.Point(0, ($y 20))
$ComboBoxArr | ForEach-Object {[void] $ComboBox.Items.Add($_)}
$ComboBox.add_SelectedIndexChanged({
$selected = $ComboBox.SelectedIndex
write-host $selected
$Label.text = “Selected: $($DropBox.Text)”
})
$form.Controls.Add($ComboBox)
$y = 60
}
[void] $form.ShowDialog()
All help is appreciated!
CodePudding user response:
In order to update the correct label you need to somehow reference it. There are a number of ways you can do this but for this example we'll keep it simple and give both the label and combobox matching names. Then inside each combobox's SelectedIndexChanged eventhandler we find the correct label by matching the name to the combobox name. Inside the eventhandler the combobox should be referred to with the $this
variable which is an automatic variable used to reference the owning object of the event.
Below is simplified code to demonstrate the main points.
$results = @('result 1', 'result2')
foreach ($result in $results) {
$Label = New-Object System.Windows.Forms.Label
$Label.Text = 'Selected:'
$form.controls.Add($Label)
# give the label a name
$label.Name = $result
$ComboBox = New-Object System.Windows.Forms.ComboBox
# give the combobox the same name
$ComboBox.Name = $result
$ComboBox.add_SelectedIndexChanged({
# reference the combobox using $this automatic variable
$selected = $this.SelectedIndex
Write-Host $selected
# find the corresponding label using the matching name
$label = $form.Controls | Where-Object { $_.Name -eq $this.Name -and $_ -is [System.Windows.Forms.Label] }
# set the correct label's text
$label.Text = “Selected: $($this.Text)”
})
$form.Controls.Add($ComboBox)
}
CodePudding user response:
You need to change the way you build the script block for the add_SelectedIndexChanged
event.
Instead of:
$comboBox.SelectedIndex
You should use:
$this.SelectedIndex
Within that event $this
will refer to the object executing the event.
It will be a little more difficult to alter how you handle $Label
and $DropBox
since those are separate objects and are not accessible from $this
.