Search This Blog

Tuesday, June 6, 2023

PowerShell: Creating Forms

To create a simple GUI you can use Windows Forms, I've previously written a post on how I created a simple game using PowerShell and Windows Forms.

In this post I will rather talk a bit about the different components available, in the form of a reference guide for building various GUI-oriented scripts.

If you have worked with Tkinter in Python, you might be familiar with the concept of putting layer upon layer, or boxes within boxes, placed with a coordinate system. It's helpful to know but not at all a requirement. Let's dig in!

For some forms it is helpful to enter this at the start:

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

Main window

For a basic app you will need a mothership that contains all the other elements such as buttons, boxes, text fields, images and the like. At the end you will also need activate the main window. The concept looks like this:

$MainWindow = New-Object System.Windows.Forms.Form
$MainWindow.text = "Stock Price Calculator"
$MainWindow.size = New-Object system.drawing.size(700,440)
$MainWindow.FormBorderStyle = "FixedDialog"

<Other code goes here>

$MainWindow.add_shown({$MainWindow.activate()})
[void] $MainWindow.ShowDialog()

In this example I've given the main window the variable name $MainWindow for the sake of simplicity. Add a dot to add additional attributes, such as .StartPosition = "CenterScreen".

Labels

Labels are pieces of text that describe something. Normally not something you want the user to interact with. It could for example describe what a textbox should contain. The location system is (x,y) where a lower x goes left and a lower y goes up. These numbers can be variables that you define outside the object. For example (($winwidth-100),($winheight-50)).

As with the main window variable, we can give labels a variable name. 

$Label_CurrentStock = New-Object System.Windows.Forms.label
$Label_CurrentStock.Location = New-Object System.Drawing.Size(100,222)
$Label_CurrentStock.Size = New-Object System.Drawing.Size(140,20)
$Label_CurrentStock.BackColor = "Gray"
$Label_CurrentStock.ForeColor = "Black"
$Label_CurrentStock.text = "Current amount of stock"
$Label_CurrentStock.textalign = "MiddleCenter"

In order for the object you create to show up on the main window add the following code. With the variable names that you use for your main window and object you are adding.

$MainWindow.Controls.Add($Label_CurrentStock)

Textbox

Textboxes are another object you might want to learn when creating Windows Forms. Just as with labels they are variables containing an object with attributes.

$Textbox_Current_Stock = New-Object System.Windows.Forms.TextBox
$Textbox_Current_Stock.Location = New-Object System.Drawing.Size(100,100)
$Textbox_Current_Stock.Size = New-Object System.Drawing.Size(140,20)
$MainWindow.Controls.Add($Textbox_Current_Stock)


Button with function

You also need intractability built into your script, so that the button for example triggers a calculation and presenting a result in a textbox. You can start off by defining the button, what size, location, color and text for example. Then you attach a function to it that is executed on being clicked.

This example shows a button that takes text from a textbox, makes it uppercase and then replaces the content in the textbox with the modified text. Here the textbox variable is called $TextboxMain and the property .Text is the content.

$ButtonUpper = New-Object System.Windows.Forms.Button
$ButtonUpper.Location = New-Object System.Drawing.Size(150,40)
$ButtonUpper.Size = New-Object System.Drawing.Size(100,200)
$ButtonUpper.TextAlign = "MiddleCenter"
$ButtonUpper.Text = "Upper Case"
$ButtonUpper.Add_Click({$TextboxMain.Text = ($TextboxMain.Text).ToUpper();})
$MainWindow.Controls.Add($ButtonUpper)

You can for example create a status bar in the bottom of your app that you write to in the same function, for example by writing $TextboxStatus.Text = "Text set to upper case"; or perhaps by turning something in your GUI green as a confirmation.

No comments:

Post a Comment