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'