'Button doesn't register the right callback [duplicate]
I'm trying to create a powershell script with a GUI where I a button per file in a directory.
I have this loop to create the button:
$i = 100
foreach($file in Get-ChildItem $savePath -recurse -include *.json) {
$filename = Split-Path $file.FullName -leaf
$saveName = $filename -split "\."
$btn = New-Object system.Windows.Forms.Button
$saveName1 = $saveName[1]
$btn.text = "Load save $saveName1"
$btn.location = New-Object System.Drawing.Point(10,$i)
$btn.width = 200
$btn.height = 30
$btn.Add_Click({
[System.Windows.Forms.MessageBox]::Show($filename.clone() , $saveName1.clone())
copy_and_print (New-Object String $filename.clone()) (New-Object String $saveName1.clone())
})
$LocalPrinterForm.controls.Add($btn)
$i = $i + 40
}
But when I click on a button the values of $filename and $saveName1 are always the one corresponding to the last file (I've added .clone() to try to avoid references issues but it doesn't fix my issue).
For example if I have those files: a.json and b.json then the MessageBox will always print b.json independently of which button I click.
How do I make sure that the right callback get registered for each button?
Solution 1:[1]
Continuing from my comment, you can utilize the button control's .Tag property to store information for that particular button to use:
$i = 100
# using -Filter is MUCH faster than -Include
foreach($file in (Get-ChildItem $savePath -Recurse -Filter '*.json' -File)) {
$btn = New-Object system.Windows.Forms.Button
$btn.text = "Load save $($file.Extension)"
$btn.location = New-Object System.Drawing.Point(10,$i)
$btn.width = 200
$btn.height = 30
# save the needed properties as object in the Tags property of the button control
$btn.Tag = $file | Select-Object FullName, Name, Extension
$btn.Add_Click({
# inside the click handler, you can refer to the button object
# itself with automatic variable $this
[System.Windows.Forms.MessageBox]::Show($this.Tag.Name, $this.Tag.Extension)
copy_and_print $this.Tag.Name $this.Tag.Extension
})
$LocalPrinterForm.controls.Add($btn)
$i += 40 # next y position
}
We do not know what your copy_and_print function does, but perhaps the first parameter should be the file's FullName. In that case change to
copy_and_print $this.Tag.FullName $this.Tag.Extension
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Theo |
