简体   繁体   中英

How do I make a Powershell WPF form run a function when loaded (and display itself)?

I have a login script in Powershell that I am using a WPF form for. I want it to load a form, and then update the form with the scripts progress.

I am using:

$Window.Add_Loaded({ 
    DoStuff
})

However, what is happening is that the script runs, and then when completed it loads the form.

If I put a button on the form to trigger the script function, the form loads, and then updates as expected, ie:

$Button.Add_Click({
    DoStuff
})

A simplified example of this is as follows:

Add-Type -AssemblyName presentationframework

[xml]$xaml = @"
<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="Window" Title="Countdown" WindowStartupLocation="CenterScreen" WindowStyle="None" Background="#2C2A6F" ResizeMode="NoResize" Width="100" Height="140">   
        <StackPanel>
            <Label Content="3" x:Name="Counter" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" FontSize="90" Padding="0,0,0,0" />
            <Button Content="Go" x:Name="Button" />
        </StackPanel>
</Window>
"@ 

$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load( $reader )

$Counter = $Window.FindName("Counter")
$Button = $Window.FindName("Button")

$Button.Add_Click({
    Countdown
})

$Window.Add_Loaded({ 

})

Function Countdown(){

    for($i=3; $i-ge 0; $i--) {
        $Counter.Content = $i
        $Window.Dispatcher.Invoke([Action]{},[Windows.Threading.DispatcherPriority]::ContextIdle);
        Start-sleep -Seconds 1
    }
}

$Window.ShowDialog()

This works, with the form loading, and then when I click the button it counts down to zero. However, if I change it to:

$Window.Add_Loaded({ 
    Countdown
})

The script runs with the form not yet visible, and then displays the counter at zero.

How can I set this so the form is shown, then the function triggered to begin the countdown automatically?

The Loaded event is triggered when entire window is ready. Last stop before rendering.

This is a bit too early for your Countdown .

Use the ContentRendered event.

$Window.Add_ContentRendered({    
    Countdown   
})

Here is a good reference Lifetime events of a WPF application

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM