WPFSamples/Full Examples/Task Dashboard.ps1


$xaml = @'
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  Title="PowerShell Cockpit"
  Width="300"
  MinWidth ="200"
  SizeToContent="Height"
  WindowStyle="ToolWindow">
    <Grid Margin="5">
      <Grid.ColumnDefinitions>
          <ColumnDefinition Width="50*"></ColumnDefinition>
          <ColumnDefinition Width="50*"></ColumnDefinition>
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
          <RowDefinition Height="Auto"></RowDefinition>
          <RowDefinition Height="Auto"></RowDefinition>
          <RowDefinition Height="*"></RowDefinition>
      </Grid.RowDefinitions>
   
      <Button Name="Job1" Width="80" Height="30" Margin="5" Grid.Column="0" Grid.Row="0">Task 1</Button>
      <Button Name="Job2" Width="80" Height="30" Margin="5" Grid.Column="1" Grid.Row="0">Task 2</Button>
      <Button Name="Job3" Width="80" Height="30" Margin="5" Grid.Column="0" Grid.Row="1">Task 3</Button>
      <Button Name="Job4" Width="80" Height="30" Margin="5" Grid.Column="1" Grid.Row="1">Task 4</Button>
      <Button Name="Job5" Width="80" Height="30" Margin="5" Grid.Column="0" Grid.Row="2">Task 5</Button>
      <Button Name="Job6" Width="80" Height="30" Margin="5" Grid.Column="1" Grid.Row="2">Task 6</Button>
 
     
    </Grid>
</Window>
'@


function Convert-XAMLtoWindow
{
    param
    (
        [Parameter(Mandatory=$true)]
        [string]
        $XAML
    )
    
    Add-Type -AssemblyName PresentationFramework
    
    $reader = [XML.XMLReader]::Create([IO.StringReader]$XAML)
    $result = [Windows.Markup.XAMLReader]::Load($reader)
    $reader.Close()
    $reader = [XML.XMLReader]::Create([IO.StringReader]$XAML)
    while ($reader.Read())
    {
        $name=$reader.GetAttribute('Name')
        if (!$name) { $name=$reader.GetAttribute('x:Name') }
        if($name)
        {$result | Add-Member NoteProperty -Name $name -Value $result.FindName($name) -Force}
    }
    $reader.Close()
    $result
}


function Show-WPFWindow
{
    param
    (
        [Parameter(Mandatory)]
        [Windows.Window]
        $Window
    )
    
    $result = $null
    $null = $window.Dispatcher.InvokeAsync{
        $result = $window.ShowDialog()
        Set-Variable -Name result -Value $result -Scope 1
    }.Wait()
    $result
}

# helper function to run code in separate thread:
function Start-InNewThread
{
    param
    (
        [ScriptBlock]$Code,
    
        [Hashtable]$Parameters = @{}
    )
  
    $powershell = [PowerShell]::Create()
    $action = {
   
        $status = $event.SourceEventArgs.InvocationStateInfo.State
    
        if ($status -eq 'Completed')
        {
            try
            {
                $powershell = $event.Sender
                $powershell.Runspace.Close()
                $powershell.Dispose()
                Unregister-Event -SourceIdentifier $event.SourceIdentifier 
            }
            catch
            {
                Write-Warning "$_"
            }
        }
    }
  
    $null = Register-ObjectEvent -InputObject $powershell -Action $action -EventName InvocationStateChanged 
    $null = $powershell.AddScript($Code)
  
    foreach($key in $Parameters.Keys)
    {
        $null = $powershell.AddParameter($key, $Parameters.$key)
    }
 
    $handle = $powershell.BeginInvoke()
}


$window = Convert-XAMLtoWindow -XAML $xaml

# Define Tasks:
$code1 = { [Console]::Beep(1000,1000) }
$code2 = { param($UI)
$UI.WriteLine('You clicked me!') }
$code3 = { Get-Service }
$code4 = { param($UI)
$UI.WriteLine((Get-Service | Out-String)) }
$code5 = { param($UI)
    $UI.WriteWarningLine('Sleeping for 5 sec while UI stays responsive')
Start-Sleep -Seconds 5}
$code6 = { $answer = [Windows.MessageBox]::Show('Do you want this?', 'My Dialog', 'YesNo') }

# Assign action to buttons:
$window.Job1.add_Click({ Start-InNewThread -Code $code1 })
$window.Job2.add_Click({ Start-InNewThread -Code $code2 -Parameter @{UI=$Host.UI} })
$window.Job3.add_Click({ Start-InNewThread -Code $code3 })
$window.Job4.add_Click({ Start-InNewThread -Code $code4 -Parameter @{UI=$Host.UI} })
$window.Job5.add_Click({ Start-InNewThread -Code $code5 -Parameter @{UI=$Host.UI} })
$window.Job6.add_Click({ Start-InNewThread -Code $code6 })

Show-WPFWindow -Window $window