0

The goal is to change text of System.Windows.Forms.Label after pressing System.Windows.Forms.Button. I have following OOP code. Which (almost) works:

Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing

class MyForm : System.Windows.Forms.Form {
    MyForm($mystuff) {
        #Do-Stuff
        $this.Add_Load( $this.MyForm_Load )
    }

    $MyForm_Load = {
        $mlabel = [System.Windows.Forms.Label]::new()
        $mlabel.Name = "status"
        $mlabel.Text = "enabled"

        $mbutton = [System.Windows.Forms.Button]::new() 
        $mbutton.Text = "toggle state"

        $mbutton.Location = [System.Drawing.Point]::new(100,100)
        $mbutton.Add_Click( $this.mbutton_click )

        $this.Controls.Add($mlabel)
        $this.Controls.Add($mbutton)
    }

    $mbutton_click = {
        if ($this.Parent.Controls["status"].Text -eq "enabled"){
            $this.Parent.Controls["status"].Text = "disabled"
        }
        else{
            $this.Parent.Controls["status"].Text = "enabled"
        }
    }
}

$foo = [MyForm]::new("test")
$foo.ShowDialog()

Now I'm trying to rewrite it to procedural style which is not working:

Add-Type -AssemblyName System.Windows.Forms    
Add-Type -AssemblyName System.Drawing


$global:mbutton = [System.Windows.Forms.Button]::new()
    $mbutton.Text = "toggle state"   
    $mbutton.Location = [System.Drawing.Point]::new(100,100)
    # $mbutton.Add_Click( {Button_Click} ) # pressing button shows errors on console


$global:mlabel = [System.Windows.Forms.Label]::new()
        $mlabel.Name = "status"
        $mlabel.Text = "enabled"

$global:Form = New-Object System.Windows.Forms.Form
    $Form.Controls.Add($mlabel)
    $Form.Controls.Add($mbutton)
    $Form.ShowDialog() | Out-Null

    $mbutton.Add_Click( {Button_Click} ) # pressing button does nothing


Function Button_Click() {
    if ($Form.Parent.Controls["status"].Text -eq "enabled"){
        $Form.Parent.Controls["status"].Text = "disabled"
    }
    else{
        $Form.Parent.Controls["status"].Text = "enabled"
    }
}

What I did wrong? How can I debug such issue?

Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122
  • I don’t have access to a computer right now to test, but this *might* be a scoping issue - you’re referring to “$global:Form” in one place and “$Form” in others. Try using “$global:Form” consistently throughout. – mclayton Dec 10 '19 at 07:31

1 Answers1

1

It's best not to use global definitions unless you absolutely need them. But in this case it WILL work if you change the order of things a little:

Add-Type -AssemblyName System.Windows.Forms    
Add-Type -AssemblyName System.Drawing

Function Button_Click() {
    if ($mlabel.Text -eq "enabled"){
        $mlabel.Text = "disabled"
    }
    else{
        $mlabel.Text = "enabled"
    }
}

$global:mbutton = [System.Windows.Forms.Button]::new()
    $mbutton.Text = "toggle state"   
    $mbutton.Location = [System.Drawing.Point]::new(100,100)
    # $mbutton.Add_Click( {Button_Click} ) # pressing button shows errors on console


$global:mlabel = [System.Windows.Forms.Label]::new()
        $mlabel.Name = "status"
        $mlabel.Text = "enabled"

$global:Form = New-Object System.Windows.Forms.Form
    $Form.Controls.Add($mlabel)
    $Form.Controls.Add($mbutton)

    $mbutton.Add_Click( {Button_Click} ) # pressing button does nothing

    $Form.ShowDialog() | Out-Null

Generally it's good practice to make showng the form the last action because you need to define everything it uses but in any case, a click event needs to be defined before you show the form...

Scepticalist
  • 3,737
  • 1
  • 13
  • 30
  • Thanks. Upvoted and accepted. It works also without `$global:` seems that main issues except wrong order of `$Form.ShowDialog() | Out-Null` and `$mbutton.Add_Click( {Button_Click} )` was also due to using `Parent` – Wakan Tanka Dec 11 '19 at 13:45