Home > Software engineering >  Powershell - Replace add_Click link on LinkLabel
Powershell - Replace add_Click link on LinkLabel

Time:08-05

I am creating a PowerShell GUI that uses a link label. My code for this link is

$ExLinkLabel = New-Object System.Windows.Forms.LinkLabel
$ExLinkLabel.Location = New-Object System.Drawing.Size(15,130)
$ExLinkLabel.Size = New-Object System.Drawing.Size(150,20)
$ExLinkLabel.LinkColor = "BLUE"
$ExLinkLabel.ActiveLinkColor = "RED"
$ExLinkLabel.Text = "Link Example"
$ExLinkLabel.add_Click({[system.Diagnostics.Process]::start("https://google.com")})
$Form.Controls.Add($ExLinkLabel)

Now say I want to change it another website later in the code based on certain conditions, I tried doing this:

$ExLinkLabel.add_Click({[system.Diagnostics.Process]::start("https://yahoo.com")})

The problem that this now has two links open, both google and then yahoo.

Is there a way to clear or just replace that first link with my new one?

Thank you

CodePudding user response:

Adding an event handler with an .add_<EventName>() method call does just that: It adds an additional event handler, of which there can be many.

In order to replace an event handler, you must first remove its old incarnation with .remove_<EventName>(), and then add the new incarnation with .add_<EventName>().

To that end, you must store the original incarnation in a variable that you can later pass to the .remove_EventName>() call:

$currEventHandler = { Start-Process https://google.com }
$ExLinkLabel.add_Click($currEventHandler)

# ...

# Remove the current event handler...
$ExLinkLabel.remove_Click($currEventHandler)
# ... and add the new one:
$currEventHandler = { Start-Process https://yahoo.com }
$ExLinkLabel.add_Click($currEventHandler)

Note that I've replaced [system.Diagnostics.Process]::start($url) with a simpler, PowerShell-idiomatic call to the Start-Process cmdlet.


In your simple case, where the two event handlers only differ by the URL they open, consider the alternative recommended by Theo:

  • Retain the original event handler and make it retrieve the URL to open from a variable defined outside the event handler, namely in the script scope. That way, all you need to do is to update the variable.
# Set the original URL
$url = 'https://google.com'

# Due to PowerShell's dynamic scoping, the event-handler script
# block - even though it runs in a *child* scope - sees the
# script scope's definition of variable $url
# You can make this cross-scope access explicit by using $script:url
# (If you wanted to *update* the variable from inside the child 
# scope $script:url *must* be used.)
$ExLinkLabel.add_Click({ Start-Process $url })

# ...

# Update the variable, after which the event handler will 
# use the new URL.
$url = 'https://yahoo.com'
  • Related