MarcoF
MarcoF

Reputation: 159

Passing index to a function in powershell

In powershell inside a foreach I generate some buttons and every button should call a function passing its index as argument but it seems that you can't pass the index to the function.

$RacesButtons = @()
for( $i=0; $i -lt $numRaces; $i++ ){
    $button = New-Object System.Windows.Forms.Button
    $RacesButtons = $RacesButtons + $button
    $RacesButtons[$i].Text = "$($RacesFiles[$i])"
    $RacesButtons[$i].Add_Click({NewNpc $i})
    $Form.Controls.Add($RacesButtons[$i])
}

It should pass 0 to 8 ($numRaces is 9) but instead it pass null and I receive this error.

Indexing operation failed. The index value of the matrix is null.
 In C:\Users\Marco\Desktop\Music&Npc\Music&Npc.ps1:137 car:2
+     $NpcDetailsTextBox.Text = $RacesFiles[$race]
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArrayIndex

"NpcDetailsTextBox" is a textbox and "RacesFiles" is an array. The strange thing is that the text of every button (setted with $RacesButtons[$i].Text = "$($RacesFiles[$i])" before setting the add_click) is correct.

I receive the same error with

$RacesButtons[$i].Add_Click({NewNpc $($i)})

But if I use one of these

$RacesButtons[$i].Add_Click({NewNpc "$i"})
$RacesButtons[$i].Add_Click({NewNpc "$($i)"})

it doesn't return an error but every button pass 0 to the function.

Any ideas on how can I solve this? Thanks in advance

Upvotes: 0

Views: 299

Answers (1)

Theo
Theo

Reputation: 61178

The reason for this is that inside the scriptblock for the Add_Click, the variable $i is unknown ($null). In this case, I would go for an easy solution and use the buttons own Tag property to save the current value of $i

$RacesButtons = for( $i = 0; $i -lt $numRaces; $i++ ){
    $button = New-Object System.Windows.Forms.Button
    $button.Text = "$($RacesFiles[$i])"
    # store the value of $i in the button's Tag property so it will be kept
    $button.Tag  = $i
    $button.Add_Click({ NewNpc $this.Tag })
    $Form.Controls.Add($button)
    # output the new button so it gets collected in the $RacesButtons array
    $button
}

Hope that helps

Upvotes: 1

Related Questions