WPF & PowerShell — Part 3 (Handling Events)

PowerShell Team

So far, most of the wpf and powershell scripts you have seen have seen just show you something, but don’t do anything that interactive.

However, In order to make real applications you need to be able to handle events. Luckily, PowerShell can make that pretty easy.

It is possible to cast a script block to an event handler. The script block has two variables: $this (which is the sender), and $_, which contains the event arguments.

Here’s a simple example of using this to click a button:

$window = New-Object Windows.Window
$eventHandler = [Windows.Input.MouseButtonEventHandler]{$this.Close()}
$window.Add_MouseDown($eventHandler)
$window.Content = "Click Me and I will Go Away"
$window.SizeToContent = "WidthAndHeight"
$null = $window.ShowDialog()

However, honestly, clicking just one button isn’t that useful.  Instead, let’s build something that will help us find commands.  The next example will help you find a command.

$window = New-Object Windows.WindowSelectCommand
$window.SizeToContent = "WidthAndHeight"
$label = New-Object Windows.Controls.Label
$label.Content = "Type A command (And watch the list change)"
$textBox = New-Object Windows.Controls.TextBox
$listBox = New-Object Windows.Controls.Listbox
$listBox.Width = 300
$listBox.Height = 200
# When the text changes, use Get-Command to display a shortened list of commands
$textBox.add_TextChanged({
    $listBox.ItemsSource = @(Get-Command "*$($textbox.Text)*" | % { $_.Name })
})
# When the listbox’s selection changes, set the text to the selection
$listBox.add_SelectionChanged({
    $textBox.Text = $listBox.SelectedItem
})
$button = New-Object Windows.Controls.Button
$button.Content = "Select Command"
$button.add_Click({$window.Close()})
$stackPanel = New-Object Windows.Controls.StackPanel
$stackPanel.Orientation="Vertical"
$children = $label, $textBox, $listbox, $button
foreach ($child in $children) { $null = $stackPanel.Children.Add($child) }
$window.Content = $stackPanel
$null = $window.ShowDialog()
$textbox.Text

In the next example, we’ll show how to use Drag and Drop to populate a listbox.

$window = New-Object Windows.WindowDragAndDrop
$window.SizeToContent = "WidthAndHeight"
$label = New-Object Windows.Controls.Label
$window.Title = $label.Content = "Drag Scipts Here, DoubleClick to Run"
$listBox = New-Object Windows.Controls.Listbox
$listBox.Height = 200
$listBox.AllowDrop = $true
$listBox.add_MouseDoubleClick({Invoke-Expression "$($listbox.SelectedItem)" -ea SilentlyContinue })   
$displayedFiles = @()
$listBox.add_Drop({
    $files = $_.Data.GetFileDropList()
    foreach ($file in $files) {
       if ($file -is [IO.FileInfo]) {
          $displayedFiles = $file
       } else {
          $displayedFiles += dir $file -recurse | ? { $_ -is [IO.FileInfo]} | % { $_.FullName }
       }
    }
    $listBox.ItemsSource = $displayedFiles | sort
})
$runButton = New-Object Windows.Controls.Button
$runButton.Content = "Run"
$runButton.add_Click({Invoke-Expression "$($listbox.SelectedItem)" -ea SilentlyContinue })
$clearButton = New-Object Windows.Controls.Button
$clearButton.Content = "Clear"
$clearButton.add_Click({$listBox.ItemsSource = @()})
$stackPanel = New-Object Windows.Controls.StackPanel
$stackPanel.Orientation="Vertical"
$children = $label, $listbox, $runButton, $clearButton
foreach ($child in $children) { $null = $stackPanel.Children.Add($child) }
$window.Content = $stackPanel
$null = $window.ShowDialog()

 

Tomorrow, we’ll make both of these relatively short (30-40 line scripts) a lot shorter and start introducing you to XAML, the cool XML format (with a lot of designer tools) you can use to write user interfaces with WPF.

Hope this helps,

James Brundage [MSFT]

0 comments

Discussion is closed.

Feedback usabilla icon