John Hang
John Hang

Reputation: 125

Not able to rename button base on value

If variable equal 1 then change the button names to reset; else change it back to as it was. However, I'm not able to make it work as it should.

I tried setting the write-host to show the variable value and it's showing correctly. However the variable number switched back once you press the button again resulting the button text not to change once you press the button. I've also tried removing the function and built it directly in the button codes. Same result.

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form                            = New-Object system.Windows.Forms.Form
$Form.ClientSize                 = '273,155'
$Form.text                       = "Rename_Test"
$Form.TopMost                    = $false

$BRename                         = New-Object system.Windows.Forms.Button
$BRename.text                    = "Rename"
$BRename.width                   = 182
$BRename.height                  = 88
$BRename.location                = New-Object System.Drawing.Point(39,26)
$BRename.Font                    = 'Microsoft Sans Serif,10'

$Form.controls.AddRange(@($BRename))

#Variables
$MyNumber = [int]1

Function AddNumber{
    $MyNumber = [int]$MyNumber + [int]1
    $BRename.text = "Reset"
}

Function SubNumber{
    $MyNumber = [int]$MyNumber - [int]1
    $BRename.text = "Rename"
}

Function GetNumber {
    $MyNumber
}

$BRename.Add_Click({

    if($MyNumber -eq [int]1){
        AddNumber
    }

    If($MyNumber -eq [int]2){
        SubNumber
    }

 })

 [void]$Form.ShowDialog()

Upvotes: 0

Views: 154

Answers (2)

f6a4
f6a4

Reputation: 1782

See comments in the code:

    Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()


# Scriptblock for button pressed

$script:MyNumber = -1

$action = {
    $script:MyNumber = -$script:MyNumber
    if( $script:MyNumber -gt 0 ) {
        $BRename.text = "Reset"
    }
    else {
        $BRename.text = "Rename"
    }
}

$form                            = New-Object system.Windows.Forms.Form
$form.Visible                    = $false
[void]$form.SuspendLayout()

$form.ClientSize                 = '273,155'
$form.text                       = "Rename_Test"
$form.TopMost                    = $false

$BRename                         = New-Object system.Windows.Forms.Button
$BRename.text                    = "Rename"
$BRename.width                   = 182
$BRename.height                  = 88
$BRename.location                = New-Object System.Drawing.Point(39,26)
$BRename.Font                    = 'Microsoft Sans Serif,10'
$BRename.Add_Click( $action )    # event must asigned before showDialog!

$Form.controls.Add($BRename)

[void]$form.ResumeLayout()
$userInput = $form.ShowDialog()

Upvotes: 0

vonPryz
vonPryz

Reputation: 24071

The reason is variable scope. Changing variable within a function doesn't - per default - change it in its parent scope. Thus

Function SubNumber{
    $MyNumber = [int]$MyNumber - [int]1

will only change $MyNumber inside the SubNumber function and the original one is not changed. This is quite akin pass-by-value schematics. The effect is that $MyNumber never is 2 and thus the subtract function is never called.

As a side note, explicit [int] is not required nor is it typical in Powershell scripts.

To change the variable in script scope, use $script: prefix within the function. Like so,

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

$Form                            = New-Object system.Windows.Forms.Form
$Form.ClientSize                 = '273,155'
$Form.text                       = "Rename_Test"
$Form.TopMost                    = $false

$BRename                         = New-Object system.Windows.Forms.Button
$BRename.text                    = "Rename"
$BRename.width                   = 182
$BRename.height                  = 88
$BRename.location                = New-Object System.Drawing.Point(39,26)
$BRename.Font                    = 'Microsoft Sans Serif,10'

$Form.controls.AddRange(@($BRename))

#Variables
$MyNumber = 1

function Renamed {
    switch ($script:MyNumber) { # Switch is usually better than multiple if statements
        1 { $BRename.text = "Reset"; ++$script:MyNumber }
        2 { $BRename.text = "Rename"; --$script:MyNumber }
        default  {$script:MyNumber = 1} # For unexpected values, force inital value
    }
}
$BRename.Add_Click({Renamed})

[void]$Form.ShowDialog()

Upvotes: 2

Related Questions