1

I'm trying to create a a new Windows Form button with my function that takes few params like size, position, Name and batchFile path that will be run when clicked. When I run it I got lots of errors like: $btnName,Location --> The property 'Location' cannot be found on this object. $btnName.Add_Click({ --> Method invocation failed because [System.String] does not contain a method name 'Add_Click'

I think that I'm passing my $btnName wrong but I don't know how to fix it or replace [string] with?
My idea is that after passing for example "buttonTest" as $btnName it would create a custom button like $buttonTest = New-Object System.Windows.Forms.Button.

Here's the code:

Add-Type -AssemblyName System.Windows.Forms

$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Copy Test"
$Form.Width = 450
$Form.Height = 300
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = 'FixedDialog'
$Form.BackColor = [System.Drawing.Color]::LightBlue
$Form.MaximizeBox = $false


$copyBatch = "test-batch.bat"


Function createBtn {
    param (
        [string]$btnName,
        [string]$btnDesc,
        [string]$batchFile,
        [int]$sizeW,
        [int]$sizeH,
        [int]$posX,
        [int]$posY
    )

    # Create a new button
    $btnName = New-Object System.Windows.Forms.Button
    $btnName.Name = $btnName
    $btnName.Text = $btnDesc
    $btnName.Width = $sizeW
    $btnName.Height = $sizeH
    $btnName.Location = New-Object System.Drawing.Point($posX, $posY)
    $btnName.Add_Click({
        $btnName.Enabled = $false  # Disable button when clicked
        Start-Process -FilePath $batchFile -Wait  # Run batch file and wait for it to finish
        $btnName.Enabled = $true  # Enable button
    })
    $Form.Controls.Add($btnName)
}

createBtn -btnName "buttonTest" -btnDesc "Copy All" -batchFile $copyBatch  -sizeW 200 -sizeH 40 -posX 200 -posY 50

$Form.ShowDialog() | Out-Null

Thanks for the help, I'm still learning :)

1 Answer 1

2

You're assigning an instance of Button to a variable that has been constrained to be a string ($btnName), use a different variable name.

As an aside, you must use .GetNewClosure() when adding the event handler, otherwise the value of $batchFile is lost. It's also a good idea to add a new parameter to your function and pass the form as argument, this way your function doesn't break when the variable $Form doesn't exist in the parent scope.

function createBtn {
    param (
        [Parameter(Mandatory)]
        [System.Windows.Forms.Form] $Form,
        [string] $btnName,
        [string] $btnDesc,
        [string] $batchFile,
        [int] $sizeW,
        [int] $sizeH,
        [int] $posX,
        [int] $posY
    )

    # Create a new button
    $btn = [System.Windows.Forms.Button]@{
        Name     = $btnName
        Text     = $btnDesc
        Width    = $sizeW
        Height   = $sizeH
        Location = [System.Drawing.Point]::new($posX, $posY)
    }

    $btn.Add_Click({
        $this.Enabled = $false
        Start-Process -FilePath $batchFile -Wait
        $this.Enabled = $true
    }.GetNewClosure())

    $Form.Controls.Add($btn)
}

$createBtnSplat = @{
    Form      = $Form
    btnName   = 'buttonTest'
    btnDesc   = 'Copy All'
    batchFile = $copyBatch
    sizeW     = 200
    sizeH     = 40
    posX      = 200
    posY      = 50
}

createBtn @createBtnSplat
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you @Santiago Squarzon, it's working like I wanted now :) I appreciate your explanation so I can understand better why it wasn't working
@Filip you mean the explanation isn't clear? Your function has a parameter named btnName typed (constrained) as string and you're trying to a assign an object of type Button to that variable so that button is coerced to a string (it is no longer a button). Not sure what else is there to explain.
I'm sorry haha I meant I appreciate that you explained it in your first response and now I can understand what was wrong (not sure why I wrote it that way, long day at work I guess 😂). Sorry you had to explain it again but thank you, everything is helpful. Have a great weekend.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.