Jay
Jay

Reputation: 13

How to tell where Powershell events handlers are invoked from?

I have a PowerShell script which creates a WinForms GUI. On the main form there are a large number of buttons (PushButtons), each with a different name/text. I'm trying to find a way to iteratively give each button a click event listener that writes the respective button's name to the console. The problem is that whenever the function is called (the function I originally passed into "$button.Add_Click({function})"), I'm not quite sure how to refer/get access to the name of the button from within this function. It's almost as if I'm no longer in the scope of the button being clicked, so I don't really have access to the button anymore.

Example:

$ButtonArray.ForEach({
    $_.Add_Click({ Say-Name })
})

function Say-Name() {
    Write-Host # How do I access the button's properties?
}

In the example above, I'm stuck at the Write-Host part. I've tried using $_ to refer to the button, but it turns out that $_ actually refers to a System.Windows.Forms.MouseEventArgs object. I've tried passing parameters in through the Add_Click script block, but that doesn't work because once I've entered the script block, I don't have access to any external information. How do I let my function know which button invoked it?

Upvotes: 1

Views: 895

Answers (1)

mklement0
mklement0

Reputation: 438198

Script blocks passed to .add_<event>() methods (the equivalent of .<event> += in C#) act as EventHandler delegates and are therefore passed two arguments:

  • the sender (the originating object): in your case, the [System.Windows.Forms.Button] that triggered the event.

  • event arguments (details): an instance of a type derived from [System.EventArgs] or, for events without arguments, the [System.EventArgs]::Empty singleton; this information is also implicitly reflected in automatic variable $_.

Therefore, to get the name of the button control at hand, declare these parameters, so you can access them:

$_.add_Click({ 
  param($sender, $eventArgs)
  $buttonName = $sender.Name
})

Upvotes: 1

Related Questions