I'm experimenting with creating GUIs and using classes in powershell. I'm really new to both of those things (and to a lesser extent powershell generally) so bear with me.
The problem I am having is I cannot make any control which makes any modification to the form. This is because when adding a handler to a button it goes into the scope of the button class in the handler and none of the form references are accessible.
Most examples of UI code in powershell are not class heavy. I realize that I could get around this, if it was not in a class, by having the handlers and form being in the global scope, but I'm trying to make use of classes so that I have the ability to make base forms and inherit from them. And I want to see what is possible.
Below is some test code including multiple of my attempts to make this work with the results commented. I even got the idea of passing the form reference into the handler (DI style). Things I'm trying are all over the map since I'm also feeling out basic powershell syntax.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
class Window : System.Windows.Forms.Form
{
Handler () {
Write-Host Handler
$this.BackColor = [System.Drawing.Color]::Blue
}
HandlerArgs ([object]$sender, [System.Eventargs]$eventArgs) {
Write-Host HandlerArgs
$this.BackColor = [System.Drawing.Color]::Blue
}
$HandlerVar = {
Write-Host HandlerVar
$this.BackColor = [System.Drawing.Color]::Blue
}
HandlerParam ($form) {
Write-Host HandlerParam
$form.BackColor = [System.Drawing.Color]::Blue
}
$HandlerVarParam = {
(params $form)
Write-Host HandlerVarParam
$form.BackColor = [System.Drawing.Color]::Blue
}
Window ()
{
$button = New-Object System.Windows.Forms.Button
$button.Text = "ClickMe"
$button.AutoSize = $true
$this.Controls.Add($button)
# $button.Add_Click( $this.Handler )
# "Cannot convert argument "value", with value: "void Handler()", for "add_Click"
# to type "System.EventHandler": "Cannot convert the "void SelectNextPage()"
# value of type "System.Management.Automation.PSMethod" to type "System.EventHandler"."
# $button.Add_Click(([System.EventHandler]$x = $this.Handler ))
# turns the window blue immediatly
# $button.Add_Click( $this.HandlerArgs )
# "Cannot convert the "void HandlerArgs(System.Object sender, System.EventArgs eventArgs)"
# value of type "System.Management.Automation.PSMethod" to type "System.EventHandler".""
# $button.Add_Click( $this.HandlerVar )
# this works but turns the button blue instead of the form
# $button.Add_Click( { $this.Handler } )
# does nothing?
# $button.Add_Click( { $this.Handler() } )
# Method invocation failed because [System.Windows.Forms.Button] does not contain a
# method named 'Handler'.
# $button.Add_Click( $this.HandlerParam($this) )
# turns the window blue immediatly
# $button.Add_Click( { $this.HandlerParam($this) } )
# Method invocation failed because [System.Windows.Forms.Button] does not contain a
# method named 'HandlerParam'.
# $button.Add_Click( $this.HandlerVarParam $this )
# parse error
# I can't find a syntax that lets me pass a param to a function in a variable
}
}
$foo = New-Object Window
$foo.ShowDialog()
Although it's likely super obvious already, c# is my main language.
Perhaps this is just a limitation of the OO support in an interpreted scripting language, or maybe it's just my syntax deficiency. Is there any pattern that will get me what I want in this class-based structure? I would hope the pattern would be a general solution for doing normal form-things with handlers of form-controls.