0

My goal is to change button text depending on text which is displayed by Label. I have following code:

Add-Type -AssemblyName System.Windows.Forms

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()
        if ($this.parent.controls["status"].text -eq "enabled"){
            $mbutton.text = "disable"
        }else{
            $mbutton.text = "enable"
        }

        $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()

But this script returns me following error:

Cannot index into a null array.
At C:\Users\wakatana\Desktop\toggle_button_name\forms2.ps1:50 char:13
+         if ($this.parent.controls["status"].text -eq "enabled"){
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : NullArray

EDIT - Final working solution:

Add-Type -AssemblyName System.Windows.Forms

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 = "label"
            $mlabel.Text = "disabled"

        $mbutton = [System.Windows.Forms.Button]::new()
            $mbutton.Name = "button"
            $mbutton.Location = [System.Drawing.Point]::new(100,100)
            $mbutton.Add_Click( $this.mbutton_click )

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

    # ----------------------------------------------
    # Now $this.controls has something. We can now access it.
    # ----------------------------------------------
        if ($this.controls["label"].text -eq "enabled"){
            $mbutton.text = "disable"
        }else{
            $mbutton.text = "enable"
        }
    }

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

$foo = [MyForm]::new("test")
$foo.ShowDialog()
Wakan Tanka
  • 7,542
  • 16
  • 69
  • 122

1 Answers1

1

Edit:

$this.parent.controls is empty for 2 reasons.

  1. Because you have not added anything to the form yet.
  2. Because you are inside $MyForm_Load, there is no need for $this.parent as you are the parent. Simply remove the .parent and access the controls directly.

E.g. Trying to access something that is empty throws the error:

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

    $mbutton = [System.Windows.Forms.Button]::new()

# ----------------------------------------------
# Here - $this.controls is empty trying to access will throw error
# ----------------------------------------------

    if ($this.controls["status"].text -eq "enabled"){
        $mbutton.text = "disable"
    }else{
        $mbutton.text = "enable"
    }

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

# ----------------------------------------------
# Here - this.controls is still empty
# ----------------------------------------------

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

# ----------------------------------------------
# Now $this.controls has something.
# ----------------------------------------------

}

So by rearranging your script to access the control after you have Added it, and by referencing $this.controls, you get:

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

    $mbutton = [System.Windows.Forms.Button]::new()

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

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

# ----------------------------------------------
# Now $this.controls has something. We can now access it.
# ----------------------------------------------

    if ($this.controls["status"].text -eq "enabled"){
        $mbutton.text = "disable"
    }else{
        $mbutton.text = "enable"
    }
}
HAL9256
  • 12,384
  • 1
  • 34
  • 46
  • thanks for reply but it is not working for me, always same error and no button text – Wakan Tanka Dec 10 '19 at 08:44
  • Ah! figured it out. It's 2 things first where you add the controls as listed earlier, and second, since your MyForm **is** the parent, you don't need to have `.parent` to reference the controls. See Edits above. – HAL9256 Dec 10 '19 at 16:22
  • thanks but I'm still getting errors under `$mbutton_click` my actual code: https://pastebin.com/AX6ZpcJU I also have some other issue with this code but I do not thing it can be related https://stackoverflow.com/questions/59258282/powershell-ignores-add-type-unless-it-is-copied-and-pasted-directly-to-console – Wakan Tanka Dec 11 '19 at 07:31
  • Thanks. Upvoded and accepted. Previously I've made mistake. I've removed `Parent` also under `$mbutton_click`. Which is still weird for me why it works like this. I've created another question regarding why `Parent` is required in one place but not in another. https://stackoverflow.com/questions/59288514/how-does-parent-works-in-system-windows-forms – Wakan Tanka Dec 11 '19 at 14:59