Refresh $WPA.label multiple times with one click?

Welcome Forums General PowerShell Q&A Refresh $WPA.label multiple times with one click?

This topic contains 22 replies, has 4 voices, and was last updated by

 
Participant
1 year, 9 months ago.

  • Author
    Posts
  • #32190

    Participant
    Points: 0
    Rank: Member

    Hi,
    so i've been trying to create my first GUI. For this question i've made a testcase. I hava an inputfield, if this -ieq "k" then first print "ok" then change it to "lets go". At the moment, it only shows Lets go.

    $WPFbutton.Add_Click({
        if($WPFtextBox.Text -ieq "k"){
         $WPFlabel.Content = "ok"
          Write-host "Updating Window"
          sleep 5        
         $WPFlabel.Content = "lets go"
         Write-host "Updating Window 2"
        }
    })
    

    Does anyone had an example? Or a suggestion? I"ve been googeling but can't find it.

  • #32193

    Participant
    Points: 0
    Rank: Member

    Does this do the trick?

    $WPFbutton.Add_Click({
        if($WPFtextBox.Text -ieq "k"){
         $WPFlabel.Content = "ok"
         $WPFlabel.Refresh()
          Write-host "Updating Window"
          sleep 5        
         $WPFlabel.Content = "lets go"
         $WPFlabel.Refresh()
         Write-host "Updating Window 2"
        }
    })
    
  • #32198

    Participant
    Points: 0
    Rank: Member

    Hi Steven,

    No sadly not. I tried that before.
    I keep getting the following error:

    Updating Window
    Method invocation failed because [System.Windows.Controls.Label] does not contain a method named 'Refresh'.
    At C:\Users\9081059\AppData\Local\Temp\dc3c8e6c-4353-4d63-8fff-2d6e22b930bc.ps1:88 char:6
    +      $WPFlabel.Refresh()
    +      ~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound
    
  • #32199

    Participant
    Points: 0
    Rank: Member

    Can you send me your full code? If not, try using .Refresh() against the form itself.

  • #32202

    Participant
    Points: 0
    Rank: Member

    Sure, no problem

    $inputXML = @"
    
        
            
                
                    
                    
                
            
    
            
                
                    
                
            
            
            
            
    
            
                
                    
                        
                        
                        
                        
                    
                
            
            
            
                
                    
                
            
            
            
            
            
        
     
    "@       
     
    $inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N'  -replace '^
    

    $Form.Refresh() results in :

    Method invocation failed because [System.Windows.Window] does not contain a met
    hod named 'Refresh'.
    At line:90 char:6
    +      $Form.Refresh()
    +      ~~~~~~~~~~~~~~~
        + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
        + FullyQualifiedErrorId : MethodNotFound
    

  • #32203

    Participant
    Points: 0
    Rank: Member

    Does seem the have problem posting the code here.
    So i pasted it in pastebin : http://pastebin.com/Npbi1U6h

  • #32204

    Participant
    Points: 0
    Rank: Member
  • #32205

    Participant
    Points: 0
    Rank: Member

    Care to share your code πŸ™‚ ? cause no mather where i place InvalidateVisual()
    $form.InvalidateVisual() or on the label, the results stays the same :'(

  • #32244

    Participant
    Points: 0
    Rank: Member

    Anyone else has an idea?

  • #32245

    Participant
    Points: 0
    Rank: Member

    Have you nanaged to get a WPF label to refresh in C#? it should be a matter of copying the method from there really. Very busy day in the office but I'm curious and will investigate later if I have time

  • #32250

    Participant
    Points: 0
    Rank: Member

    You are likely running into a common issue with PowerShell and GUIs. Since PowerShell will by default process your code as a single thread. In a lot of situations, the thread gets to processing something else, so the GUI cannot update. Check out this thread on a similar topic with a progress bar. There is also a link there to an innovative solution so that the GUI runs in a separate processing thread.

    https://powershell.org/forums/topic/progressbar-example-starting-at-wrong-value/#post-31849

  • #32251

    Participant
    Points: 0
    Rank: Member

    I don't think you will need to start using multiple threads, as in theory you are only running a method to refresh. If you were running this at the same time as trying to run a command which would take 5 seconds to invoke, I'd probably agree.

    Powershell can use whatever assemblies you import, and doesn't lack any of the ability of other languages to actually execute, only how many process it can run simultaneously.

    could you please upload your code to pastebin again? I have some free time this afternoon.

    Also, in my WinForms, I dot this in certain places, which did fix some issues powershell had with carrying out events:

    [System.Windows.Forms.Application]::DoEvents() 
    

    WPF may require something else. As I said, if you can upload again, I will have a look.

  • #32253

    Participant
    Points: 0
    Rank: Member

    I will be interested to see what Steven finds, but I can say for sure that I have seen this issue particularly with the start-sleep cmdlet since start-sleep keeps the thread from processing anything while it's sleeping. I will also say that I don't usually see this issue with labels. It's usually more complex form controls that I have seen this on, like progress bars.

  • #32286

    Participant
    Points: 0
    Rank: Member

    I have created a new GUI just for testing purposes.
    It only has one button and a label that has to change twices.
    If we get this working, i can build my full GUI again.

    My application that i needed to make is done by creating a GUI typing out every item of the layout (HTML style).
    But i hope we get this working so i can use Visual Studio to create my interfaces, it will save a lot of time.

    Anyway , the pastebin : http://pastebin.com/TjWEigZ8

    And thanks again for having a look

  • #32289

    Participant
    Points: 0
    Rank: Member
    $WPFbutton.Add_Click({
    
    	$WPFlabel1.Content = " "    
        $WPFlabel1."Getting data from AD..."
        $WPFlabel1.InvalidateVisual()
        Write-host "Updating Window"
        sleep 3
        $WPFlabel1.Content = "Succes, show results, lets go!"
        $WPFlabel1.InvalidateVisual()
        Write-host "Updating Window 2"
        
    })
    

    That works for me πŸ™‚

  • #32290

    Participant
    Points: 0
    Rank: Member

    Really?

    I tried that before, it didn't work :/
    I tried it again now, still doesn't work.

    Name Value
    —- —–
    PSVersion 5.0.10514.6
    WSManStackVersion 3.0
    SerializationVersion 1.1.0.1
    CLRVersion 4.0.30319.42000
    BuildVersion 10.0.10514.6
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
    PSRemotingProtocolVersion 2.3

  • #32293

    Participant
    Points: 0
    Rank: Member

    It's only updating once so far, which is once the method has executed.

    There are ways you can allow the label to update mid method execution, but you'd need to try to translate from C#
    Update WPF UI During Method Execution

    To be honest, If I were you, I'd use WinForms. it's tried and tested far more than WPF, and VERY easily used in PowerShell.

    I'd try translating yourself, I want to give it a go myself too!

  • #32295

    Participant
    Points: 0
    Rank: Member

    Yeah i created my first GUI now with WinForms. Just is a pitty that you can't "draw" your layout like WPF. But it will have to do i suppose.

    Its not that i'm unwilling but i'm new to Powershell, if i've got to learn C# too, it might be a bit too much. I want to focus my time on Powershell πŸ™‚

  • #32300

    Participant
    Points: 0
    Rank: Member

    I was where you were 6 months ago. Once I learnt how to use Powershell syntax inside out (by doing massive complex projects in my spare time). I started on C# and it's opened up a whole other side of Powershell, namely because you can interact with .NET better.

    Good luck πŸ™‚

    I'm actually looking at getting that method to run in powershell, so I'll let you know if I get it working.

  • #32301

    Participant
    Points: 0
    Rank: Member

    I might not be thΓ‘t talented πŸ™‚
    What projects did you work on ?

    these are things that i worked on http://pastebin.com/cJRuXnKx

  • #32677

    Participant
    Points: 0
    Rank: Member

    Well i've been ill for the past week πŸ™
    Any luck with this?

  • #64587

    Participant
    Points: 0
    Rank: Member

    I took time to port the above mentioned C# solution to native Powershell. It's actually almost identical to what is proposed in Microsoft's Dispatcher.PushFrame Method example.

    Function DoEvents()
    {
    	$frame = New-Object System.Windows.Threading.DispatcherFrame
    	[System.Windows.Threading.DispatcherOperationCallback]$CallBack = { $frame.Continue = $false }
    	$CurrentDispatcher = [System.Windows.Threading.Dispatcher]::CurrentDispatcher
    	$CurrentDispatcher.BeginInvoke("Background", $CallBack, $null)
    	[System.Windows.Threading.Dispatcher]::PushFrame($frame)
    }

    The forum's engine doesn't take XAML, so here's a pastebin working example: http://pastebin.com/0zgaVqKJ

    The button initiates a count to 5. Strangely, WPF updates the windows title but fails to update any child control. If you uncomment #DoEvent call it fixes it.

    Actually, there's a quicker fix. Instead you can use a one-liner calling this windows' dispatches with an empty action:

    $Window.Dispatcher.Invoke("Background", [action]{})

    To be honest I don't fully understand the coding esoterics behind it, the C# equivalents of these techniques are discussed here and the comments are ambiguous, some claim one solution is safer the others say the opposite. Go figure. But in my tests they both work and they both quirk. Sometimes they lag and fail to flush the event buffer in time.

  • #64621

    Participant
    Points: 0
    Rank: Member

    I took time to port the above mentioned C# solution to native Powershell. It's actually almost identical to what is proposed in Microsoft's Dispatcher.PushFrame Method example.

    Function DoEvents()
    {
    	$frame = New-Object System.Windows.Threading.DispatcherFrame
    	[System.Windows.Threading.DispatcherOperationCallback]$CallBack = { $frame.Continue = $false }
    	$CurrentDispatcher = [System.Windows.Threading.Dispatcher]::CurrentDispatcher
    	$CurrentDispatcher.BeginInvoke("Background", $CallBack, $null)
    	[System.Windows.Threading.Dispatcher]::PushFrame($frame)
    }

    The forum's engine doesn't take XAML, so here's a pastebin working example: http://pastebin.com/0zgaVqKJ

    The button initiates a count to 5. Strangely, WPF updates the windows title but fails to update any child control. If you uncomment #DoEvent call it fixes it.

    Actually, there's a quicker fix. Instead you can use this one-liner calling the windows' dispatches with an empty action:

    $Window.Dispatcher.Invoke("Background", [action]{})

    To be honest I don't fully understand the coding esoterics behind it, the C# equivalents of these techniques are discussed here and the comments are ambiguous, some claim one solution is safer the others say the opposite. Go figure. But in my tests they both work and they both quirk. Sometimes they lag and fail to flush the event buffer in time.

The topic ‘Refresh $WPA.label multiple times with one click?’ is closed to new replies.