Strange scoping (?) causes old variable value to be used in event handler

Oct 11, 2016 at 1:58 AM
I don't understand why the variable inside the -On_Click delegate uses the old variable value. How can I get it to use the new value, please?

See the On_Click method and the $Title variable below.
#Requires -Version 3.0 -Modules ShowUI

function Show {
    Param( $Title )
    Write-Host "1. Title=$Title" # Hello - OK
    $Title = "Goodbye"
    Write-Host "2. Title=$Title" # Goodbye - OK

    New-Window -Title "$Title" -SizeToContent WidthAndHeight {
        New-StackPanel -Margin 20 {
            New-Button "$Title" -On_Click { # Goodbye - OK
                Write-Host "3. Title=$Title" # Hello - What??
            }
        }
    } -Show

    Write-Host "3. Title=$Title" # Goodbye - OK
}

Show "Hello"
Coordinator
Oct 13, 2016 at 3:47 AM
That's very hard to follow, but basically the problem is when the variable gets resolved and turned into a string.

The On_Click handler isn't executed at the same time as the rest of the code, it's executing much later, when you actually click the button. At that time, it's not in the scope of the Show function, and the $Title variable ought to have no value at all ... if I had to guess, you have $Title defined in the global scope as "Hello" -- try setting $global:Title deliberately somewhere.
Oct 27, 2016 at 11:46 PM
So I think what you're saying is that if we want to refer to a script variable in an event handler, it must have been declared as global. If so, understood. Thanks!
Mar 15 at 9:49 PM
Edited Mar 15 at 9:49 PM
I'd like to extend this line of inquiry I'm having a ton of trouble with scope.

I have:
function DoSomething () {
    window {
        stackpanel { button "whoa" }
    } -show
}

function main ()
{
    Window {
        stackpanel {
            button -on_click {
                DoSomething
            }
        }
    } -show
}

main
I get this when pressing the button.

The term 'DoSomething' is not recognized as the name of a cmdlet, function, script file, or operable program...

How do enable DoSomething in the context of on_click?
Coordinator
Mar 15 at 10:33 PM
The problem is visibility. Your event handlers (and really, the whole script block for "Window") runs in the ShowUI module scope. If you paste what you have there into a console, it will work fine -- because your function is in the global scope (and thus, visible from ShowUI). Otherwise, you need to export the function to the global scope by labeling it "global:"
function global:DoSomething () {
    window {
        stackpanel { button "whoa" }
    } -show
}

function main ()
{
    Window {
        stackpanel {
            button "PopUp" -on_click {
                DoSomething
            }
        }
    } -show
}

main
Mar 15 at 11:48 PM
Ace thanks!