adepolo12
adepolo12

Reputation: 63

How to repetitively update a portion of GUI after show.dialog()?

I have a list of statuses that will need to be checked every 5 seconds, then update a panel in my gui. With my current code, I have a Timeout set to an hour and a while loop that will run the Show-Statuses function which updates the GUI.

My issue is that when this While loop is entered, the Form.ShowDialog() will never bet triggered.

How do I make it so I can show the form and the continuously update a portion of it?

Function Determine-JabadStatus {

    $JabadLOStatus = (Get-Aduser adepolo -Properties LockedOut).LockedOut

    If ($JabadLOStatus -eq $False) {
        $JabadStatusF = "Unlocked"
    } else {
        $JabadStatusF = "Locked"
    }

    $JabadStatusF
}

Function Show-Statuses {

    #Load statuses
    $JabadStatus = Determine-JabadStatus

    #Add each status seperated by + "`r`n`r`n" + quotes
    $ImportantInformationStatuses.Text = $JabadStatus 
}

$Timeout = New-TimeSpan -Hours 1
$sw = [diagnostics.stopwatch]::StartNew()

While ($sw.Elapsed -lt $Timeout) {
    Show-Statuses
    Start-Sleep -Seconds 5
}

$form.ShowDialog()

Upvotes: 1

Views: 607

Answers (2)

Drew
Drew

Reputation: 4030

Assuming your $ImportantInformationStatuses is a label or something similar, then a .Refresh() should work.

Function Show-Statuses{
    #Load statuses
    $JabadStatus = Determine-JabadStatus

    #Add each status seperated by + "`r`n`r`n" + quotes
    $ImportantInformationStatuses.Text = $JabadStatus 
    $ImportantInformationStatuses.Refresh()
}

I would recommend looking into jobs though using the windows forms timer to trigger your loop, something like this.

$JobScript = {
    If((get-aduser adepolo -Properties LockedOut).LockedOut) {
        $JabadStatusF = "Locked"
    } Else {
        $JabadStatusF = "Unlocked"
    }
    Return $JabadStatusF
}


Function JobLoop {
    $Job = Start-Job -ScriptBlock $JobScript
    $Status = (Receive-job $job -Wait)
    $ImportantInformationStatuses.Text = $Status
}

$Timer = New-Object System.Windows.Forms.Timer
$Timer.Interval = 5000
$Timer.add_tick({JobLoop})
$Timer.Start() # Do $Timer.Stop() & $Timer.Dispose() to stop the loop. 

Maybe add the .Start() to a button and the .Stop() .Dispose() to another button. Or the same button in a toggle.

Upvotes: 2

Graham J
Graham J

Reputation: 497

Try putting this into your While

 $form.Dispatcher.Invoke( [Action]{},[Windows.Threading.DispatcherPriority]::ContextIdle )

i.e.

While ($sw.Elapsed -lt $Timeout) {
    Show-Statuses
    $form.Dispatcher.Invoke( [Action]{},[Windows.Threading.DispatcherPriority]::ContextIdle )
    Start-Sleep -Seconds 5
}

I use that line of text when updating progress bars within a GUI, and when dumping output into a RichTextbox. It should work for you too.

Upvotes: 0

Related Questions