Home > other >  Want to create an Event Listener for System.Window.Form.Button
Want to create an Event Listener for System.Window.Form.Button

Time:02-03

I'm trying to loop through processes using get-process, then create a button for each process. This button, on_click, will remove the process, or right now display the text. Unfortunately, add_click event only displays text for the last process, like it's not attaching this event to the button at that iteration.

$width = 500
$dynamicFormHeight = 100
$buttonHeight = 23
$buttonWidth = 100

function GenerateForm {

    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    # System.Windows.Forms.ScrollableControl.SetScrollState(int, $true) 

    foreach ($process in (Get-Process)) {
        $processLabel = New-Object System.Windows.Forms.Label
        $processLabel.Location = New-Object System.Drawing.Size((($width / 2) - ($buttonWidth/2)), ($dynamicFormHeight - 20))
        $processLabel.Size = New-Object System.Drawing.Size($buttonWidth, $buttonHeight)
        $processLabel.Text = $process.ProcessName
        $inputform.Controls.Add($processLabel)

        $dynamicFormHeight  = $buttonHeight
        $Button = New-Object System.Windows.Forms.Button
        $Button.Location = New-Object System.Drawing.Size((($width / 2)   ($buttonWidth/2)), ($dynamicFormHeight - 20))
        $Button.Size = New-Object System.Drawing.Size($buttonWidth, $buttonHeight)
        $Button.Text = $process.ProcessName
        #$inputform.Controls.Add($Button)

        # -----PROBLEM AREA----------------
        $Button.Add_Click({
            Write-Host $Button.Text
        })
        $inputform.Controls.Add($Button)
        # -----PROBLEM AREA END----------------
    }

    
    $inputform.Size = New-Object System.Drawing.Size($width, $dynamicFormHeight)
    $inputform.StartPosition = "CenterScreen"
    $inputform.Add_Shown({$inputform.Activate()})
    [void] $inputform.ShowDialog()

}
GenerateForm

CodePudding user response:

You have to add .GetNewClosure() to the end of the .Add_Click() method.

Like this:

# -----PROBLEM AREA----------------
$Button.Add_Click({
    Write-Host $Button.Text
}.GetNewClosure())

$inputform.Controls.Add($Button)
# -----PROBLEM AREA END----------------

There is already a similar question on Stack Overflow: Similar question

CodePudding user response:

As DarkCode666 pointed out, you can use the GetNewClosure() method to create a closure and scope, but coming from a very fundamental javascript background, $this variable seems more intuitive in my opinion. @Mathias R. Jessen pointed out both

$Button = New-Object System.Windows.Forms.Button

$Button.Add_Click({
    Write-Host $this.Text
})
  •  Tags:  
  • Related