Last week I went to the Minnesota Management Summit at the Mall of America #MMSMOA, and I got inspired to work on a few projects in my backlog.
One of the presentations I went to was with Ryan Ephgrave (@EphingPosh on Twitter.com), and his talk on “Better Know a PowerShell UI“.
Overall it was a great presentation, and I learned a lot. And got me thinking about some of the things I could do with a framework I started earlier in the year but never got around to finishing.
WPF4PS
Without further adieu, I present Windows Presentation Framework for PowerShell (WPF4PS). It is also the first project I’ve released as source code on GitHub:
https://github.com/keithga/WPF4PS
Background
Most WPF + PowerShell examples are created with a lot of custom code to add in event handlers for the User Interface elements. The goal is to find all control elements on the page and if there is a pre-defined function created, then use it. Which means minimal code for overhead.
Example
Here is a fully functional example:
- Load the WPF4PS module
- Import a XAML defined in Visual Studio
- Create a scriptBlock to handle the button Click
- Create a HashTable to pass data between our script that the XAML Window
- Call the Show-XAMLWindow function
- Get the value of the TextBox from the Hash
<# .SYNOPSIS WPF4PS framework Examples .DESCRIPTION Simple Example .NOTES Copyright Keith Garner, All rights reserved. #> [cmdletbinding()] param() import-module $PSScriptRoot\wpf4ps -force $MyXAML = @" <Window x:Class="WpfApplication1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d" Title="MainWindow" FontFamily="Segoe WP Semibold" Width="400" Height="300" Name="WindowMain" > <Grid> <Label>Hello World</Label> <Button x:Name="Button1" Content="Big Red Button" Width="125" Height="25" Background="#FFDD0000" Margin="0,60,0,0"/> <TextBox x:Name="textBox1" Height="23" Width="200" /> </Grid> </Window> "@ $MyControl = [scriptBlock]{ function global:button1_click() { "Click the Big Red Button`n" + $TextBox1.TExt | show-MessageBox $WindowMain.Close() } } $MyHash = [Hashtable]::Synchronized(@{ textBox1 = "Hello World" }) Show-XAMLWindow -XAML $MyXAML -ControlScripts $MyControl -SyncHash $MyHash $MyHash.TextBox1 | Write-Host
Next
My goal is to work out the kinks and eventually upload/share this on PowerShellGallery.com.
For example:
- I created two Show-XAMLWindow() functions in the library, one inline and another Async. I still don’t know what the usage case of Async is.
- Ryan Ephgrave did some XAML + Powershell examples in his “Better Know a PowerShell UI” blog series with XAML “Binding” elements, something I have not used in the past, so I excluded them from this package.
- I had to do some weirdness with the declaring the functions above as “global” to make them visible to the Module
If you have feedback on the layout or usage, please let me know.
-k