PowerShell/WPF: Disable Button on Click PowerShell/WPF: Disable Button on Click powershell powershell

PowerShell/WPF: Disable Button on Click


As a comment above alludes to, turning the button off, doing work, and then turning it on again is on a particular thread, but not the thread that updates the GUI. It seems as though it happens instantaneously from the GUI thread perspective, i.e. off then on, nothing happens.

If you use the dispatcher to send a message to the GUI thread, i.e.

   $Window.Dispatcher.invoke([action]{$Window.btnConnect.IsEnabled -eq $False})

you would see that now you have successfully disabled the button (grayed it out) after a single click. Unfortunately, that's now a permanent situation on the GUI.

To do the "turn off, work, turn on" in a different thread, using a runspace, would go something like (forgive me if not perfect):

function my_func {   param($Window,$btnConnect)   $Runspace = [runspacefactory]::CreateRunspace()   $Runspace.ApartmentState = "STA"   $Runspace.ThreadOptions = "ReuseThread"   $Runspace.Open()   $Runspace.SessionStateProxy.SetVariable("Window",$Window)   $Runspace.SessionStateProxy.SetVariable("btnConnect",$btnConnect)    #add server name/credentials with SetVariable so they can be seen in code block    $code = {        $Window.Dispatcher.invoke(        [action] {$Window.Dispatcher.btnConnect.IsEnabled = $False})        $Window.btnConnect.Content = 'Connecting...'        Connect-CompanyVIServer -VIServer 'ServerName' -VICredential 'PSCredentialObject'        $Window.btnConnect.Content = 'Connect'        #below line throws away any clicks since we've disabled button        [System.Windows.Forms.Application]::DoEvents()        $Window.Dispatcher.invoke(        [action] {$Window.Dispatcher.btnConnect.IsEnabled = $True})    }    $PSinstance = [powershell]::Create().AddScript($code)    $PSinstance.Runspace = $Runspace    $job = $PSinstance.BeginInvoke()}$Window.btnConnect.Add_Click({  my_func $Window $Window.btnConnect})