{"id":3201,"date":"2011-07-15T07:40:00","date_gmt":"2011-07-15T15:40:00","guid":{"rendered":"http:\/\/www.sapien.com\/blog\/?p=3201"},"modified":"2011-07-15T07:41:26","modified_gmt":"2011-07-15T15:41:26","slug":"primalforms-2011-creating-responsive-loops","status":"publish","type":"post","link":"https:\/\/dev.sapien.com\/blog\/2011\/07\/15\/primalforms-2011-creating-responsive-loops\/","title":{"rendered":"PrimalForms 2011: Creating Responsive Loops"},"content":{"rendered":"<p>In the PrimalForms: Preventing Multiple Button Clicks blog article, we introduced the [System.Windows.Forms.Application]::DoEvents method, which allows the application to process form events. This method also becomes very useful when you have a script that runs through a long loop.<\/p>\n<p>Here is a sample loop with a progress bar you may encounter in your script:<\/p>\n<pre><span style=\"color: #8b0000\">$buttonProcessLoop_Click<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">{\n    <\/span><span style=\"color: #008000\">#Reset the Progress Bar<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.Value <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000000\">0<\/span><span style=\"color: #000000\">\n    \n    <\/span><span style=\"color: #0000ff\">for<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000000\">0<\/span><span style=\"color: #000000\">; <\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">-lt<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.Maximum; <\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #0000ff\">++<\/span><span style=\"color: #000000\">)\n    {\n        <\/span><span style=\"color: #008000\">#Simulate work<\/span><span style=\"color: #000000\">\n        <\/span><span style=\"color: #00008b; font-weight: bold\">sleep<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">-<\/span><span style=\"color: #000000\">Milliseconds <\/span><span style=\"color: #000000\">200<\/span><span style=\"color: #000000\">\n        \n        <\/span><span style=\"color: #008000\">#Step the progress bar<\/span><span style=\"color: #000000\">\n        <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.PerformStep() \n    }\n}<\/span><\/pre>\n<pre><span style=\"color: #000000\"><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" title=\"Progress Form\" border=\"0\" alt=\"Progress Form\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2011\/07\/Progress-Form.png\" width=\"327\" height=\"130\"><\/span><\/pre>\n<p>When we click the button, the script will go through a loop a number of times and step the progress bar to show to current position. Now if you run the form and press the button, you will notice that the form freezes while the loop is processing. <\/p>\n<p><img loading=\"lazy\" decoding=\"async\" style=\"background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px\" title=\"Not Responding\" border=\"0\" alt=\"Not Responding\" src=\"http:\/\/www.sapien.com\/blog\/wp-content\/uploads\/2011\/07\/Not-Responding.png\" width=\"327\" height=\"130\"><\/p>\n<p>As mentioned in the Preventing Multiple Buttons Clicks, this happens because the form is unable to process the pending message until the loop is complete. You can resolve this by adding the same DoEvents method we used to prevent multiple button clicks to the loop.<\/p>\n<pre><span style=\"color: #8b0000\">$buttonProcessLoop_Click<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">{\n    <\/span><span style=\"color: #008000\">#Disable the button so we don't trigger it again<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$this<\/span><span style=\"color: #000000\">.Enabled <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$false<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #008000\">#Reset the Progress Bar<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.Value <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000000\">0<\/span><span style=\"color: #000000\">\n    \n    <\/span><span style=\"color: #0000ff\">for<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000000\">0<\/span><span style=\"color: #000000\">; <\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">-lt<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.Maximum; <\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #0000ff\">++<\/span><span style=\"color: #000000\">)\n    {\n        <\/span><span style=\"color: #008000\">#Do work some work here<\/span><span style=\"color: #000000\">\n        <\/span><span style=\"color: #00008b; font-weight: bold\">sleep<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">-<\/span><span style=\"color: #000000\">Milliseconds <\/span><span style=\"color: #000000\">200<\/span><span style=\"color: #000000\">\n        \n        <\/span><span style=\"color: #008000\">#process the pending message<\/span><span style=\"color: #000000\">\n        [System.Windows.Forms.Application]<\/span><span style=\"color: #0000ff\">::<\/span><span style=\"color: #000000\">DoEvents()\n        \n        <\/span><span style=\"color: #008000\">#Step the progress bar<\/span><span style=\"color: #000000\">\n        <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.PerformStep() \n    }\n    \n    <\/span><span style=\"color: #008000\">#Enable the button so we can click it again<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$this<\/span><span style=\"color: #000000\">.Enabled <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$true<\/span><span style=\"color: #000000\">\n}<\/span><\/pre>\n<p>Now when the loop is processing you can also move the form and even click the same button so it is important to disable the loop button to prevent it from firing again. It is also important to note that since the DoEvents method allows the user to click other buttons and trigger their event blocks, this places the loop script on hold until the second event is resolved.&nbsp; Be aware that this interruption can potentially cause problems in situations where certain actions depend on the results of the original click event.<\/p>\n<p>Here is a example process flow for how Click Events are resolved during a loop when using DoEvents method:<\/p>\n<pre><span style=\"color: #008000\">#User Clicks the Loop Button<\/span><span style=\"color: #000000\">\n<\/span><span style=\"color: #ff0000\">-&gt; Enter Loop_Click Event<\/span><span style=\"color: #000000\">\n\n    <\/span><span style=\"color: #008000\">#User Clicks Button 2 while processing the loop<\/span><span style=\"color: #000000\">\n\n    <\/span><span style=\"color: #ff0000\">-&gt; Enter Button2_Click Event<\/span><span style=\"color: #000000\">\n        <\/span><span style=\"color: #008000\">#Process the Button2_Click Event<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #ff0000\">&lt;- Exit Button2_Click Event<\/span><span style=\"color: #000000\">\n\n    <\/span><span style=\"color: #008000\">#Continue Processing the Loop_Click Event<\/span><span style=\"color: #000000\">\n\n<\/span><span style=\"color: #ff0000\">&lt;- Exit Loop_Click Event<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Some users may find that they don\u2019t want to wait for the loop to finish and end up clicking on the Exit button in order to stop the process. Unfortunately, what they will find is the form will not close until the loop has completed processing. The good news is with a few slight changes you can allow the user to cancel the loop and exit the application.<\/p>\n<p>First we define a variable that will tell the loop it is time to stop:<\/p>\n<pre><span style=\"color: #8b0000\">$script:CancelLoop<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$false<\/span><\/pre>\n<p>Next we add code to the loop to evaluate the variable and see if it should stop:<\/p>\n<pre><span style=\"color: #8b0000\">$buttonProcessLoop_Click<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">{\n    <\/span><span style=\"color: #008000\">#Init CancelLoop<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$script:CancelLoop<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$false<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$buttonCancelLoop<\/span><span style=\"color: #000000\">.Enabled <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$true<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #008000\">#Disable the button so we don't trigger it again<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$this<\/span><span style=\"color: #000000\">.Enabled <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$false<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #008000\">#Reset the Progress Bar<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.Value <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000000\">0<\/span><span style=\"color: #000000\">\n    \n    <\/span><span style=\"color: #0000ff\">for<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000000\">0<\/span><span style=\"color: #000000\">; <\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">-lt<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.Maximum; <\/span><span style=\"color: #8b0000\">$i<\/span><span style=\"color: #0000ff\">++<\/span><span style=\"color: #000000\">)\n    {\n        <\/span><span style=\"color: #008000\">#Do work some work here<\/span><span style=\"color: #000000\">\n        <\/span><span style=\"color: #00008b; font-weight: bold\">sleep<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">-<\/span><span style=\"color: #000000\">Milliseconds <\/span><span style=\"color: #000000\">200<\/span><span style=\"color: #000000\">\n        \n        <\/span><span style=\"color: #008000\">#process the pending message<\/span><span style=\"color: #000000\">\n        [System.Windows.Forms.Application]<\/span><span style=\"color: #0000ff\">::<\/span><span style=\"color: #000000\">DoEvents()\n        \n        <\/span><span style=\"color: #0000ff\">if<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #8b0000\">$script:CancelLoop<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">-eq<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$true<\/span><span style=\"color: #000000\">)\n        {\n            <\/span><span style=\"color: #008000\">#Clear the progress bar<\/span><span style=\"color: #000000\">\n            <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.Value <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000000\">0<\/span><span style=\"color: #000000\">\n            <\/span><span style=\"color: #008000\">#Exit the loop<\/span><span style=\"color: #000000\">\n            <\/span><span style=\"color: #0000ff\">break<\/span><span style=\"color: #000000\">;\n        }\n        <\/span><span style=\"color: #008000\">#Step the progress bar<\/span><span style=\"color: #000000\">\n        <\/span><span style=\"color: #8b0000\">$progressbar1<\/span><span style=\"color: #000000\">.PerformStep() \n    }\n    \n    <\/span><span style=\"color: #008000\">#Enable the button so we can click it again<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$this<\/span><span style=\"color: #000000\">.Enabled <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$true<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$buttonCancelLoop<\/span><span style=\"color: #000000\">.Enabled <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$false<\/span><span style=\"color: #000000\">\n}<\/span><\/pre>\n<p>We can add a Cancel Button so the user can stop the stop the loop process. We define the Cancel button\u2019s click event as follows:<\/p>\n<pre><span style=\"color: #8b0000\">$buttonCancel_Click<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">{\n  <\/span><span style=\"color: #000000\">    <\/span><span style=\"color: #8b0000\">$script:CancelLoop<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$true<\/span><span style=\"color: #000000\">\n}<\/span><\/pre>\n<pre><span style=\"color: #000000\"><\/span>&nbsp;<\/pre>\n<p>In addition, we want to exit the loop if the user tries to close the application. We can handle this by using the forms Closing event:<\/p>\n<pre><span style=\"color: #8b0000\">$form1_FormClosing<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">[System.Windows.Forms.FormClosingEventHandler]{\n<\/span><span style=\"color: #008000\">#Event Argument: $_ = [System.Windows.Forms.FormClosingEventArgs]<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$script:CancelLoop<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$true<\/span><span style=\"color: #000000\">\n}<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Next we must handle any exit buttons. If you are using the button\u2019s DialogResult property, you are not&nbsp; required to create a click event block that calls the $form1.Close() method (See: <a href=\"http:\/\/www.sapien.com\/blog\/2011\/06\/07\/primalforms-2011-spotlight-on-the-button-control\/\">Spotlight on the Button Control<\/a>). But this presents an unexpected issue because if you click the button the FormClosing event will not trigger until after the loop has completed. Therefore, you will have to define a click event for the exit button and set the <span style=\"color: #8b0000\">$script:CancelLoop <\/span>variable to false.<\/p>\n<pre><span style=\"color: #8b0000\">$buttonExit_Click<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">{\n    <\/span><span style=\"color: #008000\">#The Exit Button has DialogResult = Cancel<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #008000\">#So we don't have to call $form1.Close method<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #008000\">#But the Closing event will not trigger until<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #008000\">#the loop is finished processing<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #008000\">#So we just tell the loop to stop<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$script:CancelLoop<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8b0000\">$true<\/span><span style=\"color: #000000\">\n}<\/span><\/pre>\n<p>If you do not have the button\u2019s DialogResult property set, you can explicitly close the form in the button\u2019s click event and it will trigger the Form\u2019s Closing event.<\/p>\n<pre><span style=\"color: #8b0000\">$buttonExit_Click<\/span><span style=\"color: #0000ff\">=<\/span><span style=\"color: #000000\">{\n    <\/span><span style=\"color: #008000\">#Tell the form to close and the FormClosing event will trigger<\/span><span style=\"color: #000000\">\n    <\/span><span style=\"color: #8b0000\">$form1<\/span><span style=\"color: #000000\">.Close()\n}<\/span><\/pre>\n<p>Now you have a responsive form in which you can exit the processing loop by clicking on the Cancel button or by simply exiting the application.<\/p>\n<p>You can download the sample <a href=\"http:\/\/www.sapien.com\/downloads#Sample Scripts\/PrimalForms 2011\/ResponsiveLoop.zip\">Responsive Loop Form<\/a> from the <a href=\"http:\/\/sapien.com\/downloads\">Downloads<\/a> section.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the PrimalForms: Preventing Multiple Button Clicks blog article, we introduced the [System.Windows.Forms.Application]::DoEvents method, which allows the application to process form events. This method also becomes very useful when you have a script that runs through a long loop. Here is a sample loop with a progress bar you may encounter in your script: $buttonProcessLoop_Click={ [&hellip;]<\/p>\n","protected":false},"author":10,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[283,509,575,25],"tags":[652,665,664,28,314,633,663],"class_list":["post-3201","post","type-post","status-publish","format-standard","hentry","category-howto","category-primalforms-software-news","category-primalforms-2011-software-news","category-windows-powershell","tag-button","tag-form","tag-loop","tag-powershell","tag-primalforms","tag-primalforms-2011","tag-progressbar"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/3201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/comments?post=3201"}],"version-history":[{"count":2,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/3201\/revisions"}],"predecessor-version":[{"id":3205,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/posts\/3201\/revisions\/3205"}],"wp:attachment":[{"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/media?parent=3201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/categories?post=3201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.sapien.com\/blog\/wp-json\/wp\/v2\/tags?post=3201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}