How to let an event handler inside of a function modify a parameter passed by reference?

Viewed 95

I'm using functions to create different WinForm elements; for example, RadioButtons inside of a GroupBox. I'm trying to pass in a variable representing the currently selected RadioButton that gets updated whenever a new one is selected.

function New-RadioButton
{
    [OutputType([System.Windows.Forms.RadioButton])]
    param
    (
        [int]    $LocationX,
        [int]    $LocationY,
        [string] $Label,
        [System.Windows.Forms.RadioButton] $SelectedRB
    )

    $newButton          = New-Object System.Windows.Forms.RadioButton
    $newButton.Text     = $Label
    $newButton.AutoSize = $false
    $newButton.Bounds   = New-Object System.Drawing.Rectangle($LocationX, $LocationY, $RBWidth, $RBHeight)

    $newButton.Add_CheckedChanged({
        if($newButton.Checked) {
            $SelectedRB = $newButton
        }
    }.GetNewClosure())

    return $newButton
}

function New-GroupBox
{
    [OutputType([System.Windows.Forms.GroupBox])]
    param
    (
        [int] $LocationX,
        [int] $LocationY,
        [System.Windows.Forms.RadioButton] $SelectedRB
    )

    $rb1 = New-RadioButton $RBx $RB1y 'One' $SelectedRB
    $rb2 = New-RadioButton $RBx $RB2y 'Two' $SelectedRB

    $groupBox          = New-Object System.Windows.Forms.GroupBox
    $groupBox.AutoSize = $false
    $groupBox.Bounds   = New-Object System.Drawing.Rectangle($LocationX, $LocationY, $GBWidth, $GBHeight)

    $groupBox.Controls.AddRange(@($rb1, $rb2))

    return $groupBox
}

$Selection1 = New-Object System.Windows.Forms.RadioButton
$GroupBox1  = New-GroupBox $GB1x $GB1y $Selection1

$Selection2 = New-Object System.Windows.Forms.RadioButton
$GroupBox2  = New-GroupBox $GB2x $GB2y $Selection2

In specific, I'm using a script block inside of $newButton.Add_CheckChanged(), and trying to access the scope of the parent function to get and set the selection variable passed by reference. I'm not super proficient with PowerShell, I'm trying to write this like a lambda in C# and capture the scope of the parent. However, I know that this doesn't necessarily work in PowerShell - I've added {}.GetNewClosure(), but this only copies the current scope at creation time, not run-time.

I know that I could create script-wide variables (i.e. a script:$Selection or storing them in a hash table), but is there a solution that is agnostic to the name of the variable itself?

Edit: For reference, I'm using PowerShell 5.1.

0 Answers
Related