Learn about Windows PowerShell
About the author: Doug Finke is a Microsoft PowerShell MVP working for Lab49, a company that builds advanced applications for the financial service industry. Over the last 20 years, Doug has been a developer and author working with numerous technologies. You can catch up with Doug on his blog.
The Scripting Guys recently posted Weekend Scripter: Creating a GUI for a Windows PowerShell Script, in which Ed Wilson builds a Windows form GUI application for a Windows PowerShell script. In today’s post, I’ll build the same GUI application but with the Windows Presentation Foundation PowerShell Kit (WPK).
WPK allows you to build rich user interfaces entirely with Window PowerShell scripts. WPK provides more than 600 cmdlets, which allow you to add WPF buttons, grids, list boxes, and more to Windows forms.
James Brundage, author of WPK, says “WPK pays homage to Tcl/Tk.” Tcl (pronounced “Tickle”) is a programming language created in 1990 by John Ousterhout when he was a professor at the University of California, Berkeley.
You need to download and install the Microsoft PowerShell Power Pack to try out these examples.
WPK provides access to the presentation layer in WPF, surfacing controls in the standard Verb-Noun form. This example shows how you can add a label to a window and display, “Hello World.” In addition, each control has parameters. For the New-Window cmdlet, we are using four parameters: Height, Width, Show, and Content. In the example, the Content parameter is implied so that we can shorten the script by leaving it out. It would come after the Show parameter.
Import-Module WPK
New-Window -Height 125 -Width 300 -Show {
New-Label "Hello World" -FontSize 50
}
First, you need to download WPK from the MSDN Code Gallery. WPK lets you create rich user interfaces quick and easily from Windows PowerShell. Think HTA, but easy.
New-Window -Title "Trip Cost" -WindowStartupLocation CenterScreen `
-Width 300 -Height 200 -Show {
New-Grid -Rows 32, 32*, 32*, 32* -Columns 100, 100* {
New-Button -Content "_Calculate" -Row 0 -Column 0 -Margin 3 -On_Click {
$txtTotalCost = $Window | Get-ChildControl txtTotalCost
$txtMiles = $Window | Get-ChildControl txtMiles
$txtMilesPerGallon = $Window | Get-ChildControl txtMilesPerGallon
$txtCostPerGallon = $Window | Get-ChildControl txtCostPerGallon
$txtTotalCost.Text = `
"{0:n2}" -f (($txtMiles.Text / $txtMilesPerGallon.Text) `
* $txtCostPerGallon.Text)
New-TextBox -Name txtTotalCost `
-Row 0 -Column 1 -Margin 3
New-TextBlock -Text "Miles" `
-Row 1 -Column 0 -VerticalAlignment Center -Margin 3
New-TextBox -Name txtMiles `
-Row 1 -Column 1 -Margin 3 -Text 100
New-TextBlock -Text "Miles Per Gallon" `
-Row 2 -Column 0 -VerticalAlignment Center -Margin 3
New-TextBox -Name txtMilesPerGallon `
-Row 2 -Column 1 -Margin 3 -Text 23
New-TextBlock -Text "Cost Per Gallon" `
-Row 3 -Column 0 -VerticalAlignment Center -Margin 3
New-TextBox -Name txtCostPerGallon `
-Row 3 -Column 1 -Margin 3 -Text 2.50
WPK is a Windows PowerShell module. To use a module, you first need to import it using the Import-Module cmdlet.
The Trip Cost GUI uses these WPK cmdlets:
New-Window
Creates a new System.Windows.Window
New-Grid
Creates a new System.Windows.Controls.Grid
New-Button
Creates a new System.Windows.Controls.Button
New-TextBox
Creates a new System.Windows.Controls.TextBox
New-TextBlock
Creates a new System.Windows.Controls.TextBlock
The New-Window cmdlet creates a WPF Window. The parameters in the example create a 300-by-200 window, sets the title, centers the screen, and shows it.
Nested inside the New-Window cmdlet is the New-Grid cmdlet. The Rows and Columns parameters are used to create a table having 2 columns and 4 rows. The * tells WPF that that controls contained in the grid will adjust when the window is resized.
Notice that the TextBox and TextBlock controls defined inside the New-Grid cmdlet use the –Row and –Column parameters, which creates the screen layout. The new button Calculate is at Row 0, Column 0, which can be seen at the top of the window.
Also, each New-TextBox cmdlet uses the –Name parameter. This is important because you use these names to access the controls properties.
When the user clicks the Calculate button, we need do the calculation. This is done with the -On_Click parameter. It takes a ScriptBlock and in here we retrieve the text box controls by name. For example, this line of script looks for a control named txtTotalCost in the set of controls for the window being displayed.
$Window is set when the New-Window cmdlet is used. Piping this variable to the Get-ChildControl cmdlet and specifying the control name (txtTotalCost, in this case) finds that control and stores it in the variable, $txtTotalCost. Now we can access any property on that WPF control. In our case, we will access the Text property.
For each control whose properties you want to access, you need to use the $Window |Get-ChildControl cmdlet to get an instance of it so that you can manipulate it.
Now we can calculate the trip cost:
The WPK version is less lines of code to get the same result as the Windows forms version. Though it requires learning a new approach and new commands, there are advantages. For instance, if you resize the window, you can see that the text blocks and text boxes resize automatically without any extra coding on your part. Note: The Calculate button and its associated text box do not resize. This is because we did not specify an * after the 32 and 100 in the Rows and Columns properties.
Hi,
Sorry about the question. I'm just starting with the PowerShell.
I'm trying to make a modified version of the The Trip Cost WPK GUI.
The problem is when I try to sum the values with the operator '+', it gives the result as a string. I know that it should give the result as a string as it calls the .Text property but in your example it does the math.
So if I put <code> $TotalCost.Text = $fuelcost + $food + $accomodation <code>
and then I enter 50 in the fuelcost textbox, 50 in the food textbox and 50 in the accomodation textbox, when a click Calculate it should give me 150, but it gives 505050
I tryed to remove the Text property but it throws an error saying that there's no addition operation set in the New-TextBox function.
Any ideas?
Thanks
Hi again,
I got it. I just had to cast the variables. e.g. [int]
Cheers
I know it's a few years too late, but thanks for sharing, someone just referred me here from social.technet.