none
powershell form gui button issue

    Question

  • hey, I need some help with my PS script,

    if I let run the following script, all buttons have the same action assigned (all buttons are linked to server05),

    (see the bold marked line)

    is there a way to fix that issue without decline single buttons, I would like to prefer to use it in a foreach loop,

    the script should be used later for 30 servers (30 buttons and labels as well)

    =============================================================================

    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    [Windows.Forms.Application]::EnableVisualStyles()

    $Form0 = New-Object System.Windows.Forms.Form
    $Form0.Text = "Box Start Menu"
    $Form0.ClientSize = New-Object System.Drawing.Size(600, 400)

    $array1 =
    (
    "Server01,40",
    "Server02,62",
    "Server03,84",
    "Server04,106",
    "Server05,128"
    )

    foreach ($item in $array1)
        {
        $1 = $item.Split(",")
        $11 = $1.GetValue(0)
        $12 = $1.GetValue(1)
        
        $Button0 = New-Object System.Windows.Forms.Button
        $Button0.BackColor = "LightGreen"
        $Button0.Size = New-Object System.Drawing.Size(150, 20)
        $Button0.Font = New-Object System.Drawing.Font("Times New Roman", 10, [System.Drawing.FontStyle]::Regular)
        $Button0.Text = $11
        $Button0.Location = New-Object System.Drawing.Point(50, $12)
        $Button0.Add_Click({mstsc C:\Users\User1\Servers\$11.RDP})
        $Form0.Controls.Add($Button0)
        }

    $GroupBox0 = New-Object System.Windows.Forms.GroupBox
    $GroupBox0.Size = New-Object System.Drawing.Size(520, 200)
    $GroupBox0.Location = New-Object System.Drawing.Point(30, 20)
    $Form0.Controls.Add($GroupBox0)

    $Button100 = New-Object System.Windows.Forms.Button
    $Button100.BackColor = "White"
    $Button100.Font = New-Object System.Drawing.Font("Microsoft Sans Serif", 8.25, [System.Drawing.FontStyle]::Regular)
    $Button100.ForeColor = "ControlText"
    $Button100.Text = "Cancel"
    $Button100.Add_Click({$Form0.Close()})
    $Button100.Size = New-Object System.Drawing.Size(100, 23)
    $Button100.Location = New-Object System.Drawing.Point(29, 250)
    $Form0.Controls.Add($Button100)
        
    [void]$Form0.ShowDialog()

    Tuesday, March 28, 2017 8:58 AM

Answers

All replies

  • Hi Higgins,

    basically, your form evaluates the content of $11 only when pressing the button. Since you generate all the buttons in a row, it'll resolve to the last name.

    The way to work around this is to get the name in the variable when you create the ScriptBlock, not when you use it. Furthermore, you need to work on the variable names. Numeric names are ... not recommended. Makes the script harder to maintain. Here's a rewrite of your loop that should address both issues:

    foreach ($item in $array1)
    {
    	
    	$ServerName = $item.Split(",")[0]
    	$FormOffset = $item.Split(",")[1]
    	
    	$Button0 = New-Object System.Windows.Forms.Button
    	$Button0.BackColor = "LightGreen"
    	$Button0.Size = New-Object System.Drawing.Size(150, 20)
    	$Button0.Font = New-Object System.Drawing.Font("Times New Roman", 10, [System.Drawing.FontStyle]::Regular)
    	$Button0.Text = $ServerName
    	$Button0.Location = New-Object System.Drawing.Point(50, $FormOffset)
    	$ScriptBlock = [System.Management.Automation.ScriptBlock]::Create("mstsc C:\Users\User1\Servers\$ServerName.RDP")
    	$Button0.Add_Click($ScriptBlock)
    	$Form0.Controls.Add($Button0)
    }

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Tuesday, March 28, 2017 9:22 AM
  • quick and brilliant,

    many thanks, Fred

    vielen, vielen dank

    • Marked as answer by higgins63 Tuesday, March 28, 2017 12:21 PM
    Tuesday, March 28, 2017 9:46 AM
  • Here is another way to define a single custom script that works for al buttons:

    $Button0.Add_Click({
    		$servername = $this.Name
    		mstsc "C:\Users\User1\Servers\$ServerName.RDP"
    	}
    )

    "$this" always is the current button that is being clicked.

    Every event has two default arguments:

    button1_Click(object sender, System.EventArgs e)

    In PowerShell $this is set to "sender" and $_ is set to "e".

    This is true of ALL control events.

    See: https://msdn.microsoft.com/en-us/library/system.windows.forms.control.click(v=vs.110).aspx


    \_(ツ)_/



    • Edited by jrv Tuesday, March 28, 2017 12:29 PM
    Tuesday, March 28, 2017 12:24 PM
  • Hi jrv,

    sorry, but your variation doesn't work,

    however, Fred's solution (see above) is fine for me

    thx

    Wednesday, March 29, 2017 10:43 AM
  • It has worked for me for many years.  Perhaps you didn't use it correctly.

    Anyway.  Fred's method also works so use it if it solves your issue.


    \_(ツ)_/

    Wednesday, March 29, 2017 6:18 PM
  • This works just fine:

    Add-Type -AssemblyName System.Windows.Forms
    $form = [System.Windows.Forms.Form]::new()
    $button = [System.Windows.Forms.Button]::new()
    $form.Controls.Add($button)
    $button.Dock = 'Fill'
    $button.Text = 'My button'
    $button.Name = 'button1'
    $button.add_Click({
        Write-Host $this.Text
        Write-Host $this.Name
    })
    $form.ShowDialog()
    Take a bit of time to learn how forms and PowerShell work.  You will find that most things are very easy once you learn the basics.


    \_(ツ)_/

    Wednesday, March 29, 2017 6:24 PM
  • jrv,

    your code works only for me when I change $this.name by $this.text

    the $button0 has no .name , but a .text property defined

    so I think, if you had checked my script code correctly, the mistake could have been prevented :)

    $Button0.Add_Click({
    		$servername = $this.Name
    		mstsc "C:\Users\User1\Servers\$ServerName.RDP"
    	}
    )
    Tuesday, April 18, 2017 2:05 PM
  • All controls have a "name" property.  You cannot use "Text" to find a control

    $button.Name = 'MyButton'
    $form.Controls['MyButton']

    This will find any control be name. 

    Yes.  You can use "Text" to identify a button.

    Go back and read my example more carefully.


    \_(ツ)_/

    Tuesday, April 18, 2017 6:43 PM