How to update GUI when running a function, or a series of functions

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 4 years and 1 month old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
flho_fvr
Posts: 6
Last visit: Mon Nov 21, 2022 11:14 pm

How to update GUI when running a function, or a series of functions

Post by flho_fvr »

Hi
Trying to get a gui to display a message "configurering... please wait, and then call the function, and at the end update with a final "all processed" wait 3 seconds and close the gui.
  1. Function updateConfig
  2. {
  3.     <doing some stuff>
  4.     $endDate = Get-Date
  5.     $statusMessage = "All processed ($endDate), please wait...!"
  6.     $richtextbox1.Text = $statusMessage
  7.     $richtextbox1.Update()
  8.     Start-Sleep -Seconds 3
  9.     $formUpdateConfiguration.Close()
  10. }
  11.  
  12. $formUpdateConfiguration_Load = {
  13.     $date = Get-Date
  14.     $statusMessage = "Configuring ($date), please wait..."
  15.     $richtextbox1.Text = $statusMessage
  16.     $richtextbox1.Update()
  17.     updateConfig
  18. }
The reason for autoclose is that I have 3 functions to execute, and another, and maybe better, approach would be displaying a GUI, run the 3 functions and update the GUI for every function.

Any ideas?

Best regards
/Flemming
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: How to update GUI when running a function, or a series of functions

Post by jvierra »

You will have to force an update after you change a control. This is usually done by executing the following line:
[System.Windows.Forms.Application]::DoEvents()

The thing to keep in mind id that a GUI executes all code in an event. As long as the code in teh event is executing the GUI will remain frozen. "DoEvents" allows the form to process messages and update controls.
flho_fvr
Posts: 6
Last visit: Mon Nov 21, 2022 11:14 pm

Re: How to update GUI when running a function, or a series of functions

Post by flho_fvr »

Hi jvierra

Thanks for you help - I do appreciate it.

It seem's I'm still doing it wrong... tried to do the following, but it seem's Im not using your suggestion correctly - can you help me out?
  1. function loadOne
  2. {
  3.     [System.Windows.Forms.Application]::DoEvents()
  4.     $Script:oneDate = Get-Date
  5.     $statusMessage = "$([char]0x2022) Configuring partOne ($oneDate), please wait..."
  6.     $richtextbox1.Text = $statusMessage
  7.     Write-Host "One"
  8.     Start-Sleep -Seconds 3
  9. }
  10.  
  11. function loadTwo
  12. {
  13.     [System.Windows.Forms.Application]::DoEvents()
  14.     $Script:twoDate = Get-Date
  15.     $statusMessage = "$([char]0x2022) Configuring partOne ($oneDate), please wait...`n$([char]0x2022) Configuring partTwo ($twoDate), please wait..."
  16.     $richtextbox1.Text = $statusMessage
  17.     Write-Host "Two"
  18.     Start-Sleep -Seconds 3
  19. }
  20.  
  21. function loadThree
  22. {
  23.     [System.Windows.Forms.Application]::DoEvents()
  24.     $Script:threeDate = Get-Date
  25.     $statusMessage = "$([char]0x2022) Configuring partOne ($oneDate), please wait...`n$([char]0x2022) Configuring partTwo ($twoDate), please wait...`n$([char]0x2022) Configuring partThree ($threeDate), please wait..."
  26.     $richtextbox1.Text = $statusMessage
  27.     Write-Host "Three"
  28.     Start-Sleep -Seconds 3
  29. }
  30.  
  31. function Completed
  32. {
  33.     [System.Windows.Forms.Application]::DoEvents()
  34.     $completedDate = Get-Date
  35.     $statusMessage = "$([char]0x2022) Configuring partOne ($oneDate), please wait...`n$([char]0x2022) Configuring partTwo ($twoDate), please wait...`n$([char]0x2022) Configuring partThree ($threeDate), please wait...`n$([char]0x2022) All configuring Completed ($completedDate)!"
  36.     $richtextbox1.Text = $statusMessage
  37.     Start-Sleep -Seconds 3
  38.     Write-Host "Completed"
  39.     $formUpdateConfiguration.Close()
  40. }
  41.  
  42. $formUpdateConfiguration_Load = {
  43.     loadOne
  44.     loadTwo
  45.     loadThree
  46.     Completed
  47. }
I can see the write-host statement coming on screen in the correct flow... but no gui is shown until the end where it blinks, as it shuts down at once.

Best regards
/Flemming
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: How to update GUI when running a function, or a series of functions

Post by jvierra »

You have to add it after you alter a control and not at the beginning of a function. Every line in the function will block. The function will remain blocked until the event that called it exits.

This is why we tend to avoid functions in Windows events. It makes the code harder to follow and is normally not necessary. In your case I see no reason to use functions. They add nothing to the code and make it harder to use, read and understand.

Do not use Start-Sleep in Windows events. It serves no purpose and will block solidly with no hope of the Form receiving any updates. Remember that forms are served by the message loop. Every line of code blocks the message loop. All updates to controls go through the message loop or the dispatcher. This is the hardest thing for non-programmers to understand. Windows is an event based system. Forms are a message dispatch system. Any code executing in a form blocks the message loop. "DoEvents" causes the system to process any queued messages in the message queue. If you do something that changes a property on a control then the DoEvents() call will allow the form to process the change. The DoEvents() must come immediately after the line that makes the change.

See: https://docs.microsoft.com/en-us/dotnet ... mework-4.8
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: How to update GUI when running a function, or a series of functions

Post by jvierra »

Running code in the "Load" event will block the form from being shown until the code finishes executing. The Load event cannot use the DoEvents() method because the form has not yet been loaded. "Load" occurs after all controls have been created but before the form is actually shown. To run code after the form is displayed you must run the code in the "FormShown" event. This event occurs after the form has been displayed.

See the following article on how to use events in forms. Events are not all equal and a good understanding of what events are and how the work and propagate is critical to the coding of forms.

https://docs.microsoft.com/en-us/dotnet ... dows-forms
flho_fvr
Posts: 6
Last visit: Mon Nov 21, 2022 11:14 pm

Re: How to update GUI when running a function, or a series of functions

Post by flho_fvr »

Hi jvierra

Thanks for your help, I have now come up with a solution that works for me - and thanks for your explanation about the message loop/dispatcher.

Best regards
/Flemming
This topic is 4 years and 1 month old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked