1

Is such a creation of objects in a loop correct? I do it this way and it works. But maybe I'm wrong and there is a more literate way. Thank you.

0..10 | ForEach-Object {    

    New-Variable "Button$_" -EA 0
    (Get-Variable "Button$_").Value = New-Object System.Windows.Forms.Button

    $Button = (Get-Variable "Button$_").Value
    $Button.FlatStyle = 'Flat'
    ... 
}

Editing. I mean the correctness of this part:

New-Variable "Button$_" -EA 0
(Get-Variable "Button$_").Value = New-Object System.Windows.Forms.Button
0

2 Answers 2

1

Assuming you really want to create distinct variables $Button1, $Button2, ... rather than storing your button objects in a single array variable:

New-Variable "Button$_" -EA 0
(Get-Variable "Button$_").Value = New-Object System.Windows.Forms.Button

works, but can more simply and more efficiently be written as:

Set-Variable "Button$_" (New-Object System.Windows.Forms.Button)

Note: The "..." around Button$_ isn't strictly necessary here, but it makes the intent clearer.

or, in PSv5+:

Set-Variable "Button$_" ([System.Windows.Forms.Button]::new())

If you want to obtain a reference to the newly created variable object at the same time, using
-PassThru:

$buttonVar = Set-Variable -PassThru "Button$_" ([System.Windows.Forms.Button]::new())
$buttonVar.Value.FlatStyle = 'Flat'

Alternatively, you can store the button object directly in an aux. variable with a fixed name:

Set-Variable "Button$_" ($button = [System.Windows.Forms.Button]::new())
$button.FlatStyle = 'Flat'

Note how the variable assignment ($button = ...) is part of the constructor expression.

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

1 Comment

Thank you. This is the complete answer for me. Success to you.
1

I would rather use a collection to store button attributes and loop through it to create one by one from that.

Then you have full control on the attributes of the button that you want to create.

$Buttons = @(
    @{ Name='ABC'; Val=100; FlatStye='Flat'; Xpos=35; Ypos=30}
    @{ Name='EFG'; Val=101; FlatStye='Flat'; Xpos=35; Ypos=60 }
    @{ Name='XYZ'; Val=102; FlatStye='Popup'; Xpos=35; Ypos=90 }
    @{ Name='MNL'; Val=102; FlatStye='Popup'; Xpos=35; Ypos=120 }
    )

Function Generate-Form {

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

    # prepare Form
    $Form = New-Object System.Windows.Forms.Form
    $Form.Text = "My Form"
    $Form.Size = New-Object System.Drawing.Size(400,400)
    $Form.StartPosition = "CenterScreen"
    $Form.Topmost = $True

    # Add Buttons from collection
    foreach ($btn in $Buttons) {

    $Button = [System.Windows.Forms.Button] @{
       FlatStyle = $btn.FlatStye
        Name = $btn.Name
        Text = $btn.Name
        Location  = New-Object System.Drawing.Size($btn.Xpos, $btn.Ypos )
        Size = New-Object System.Drawing.Size(220,25)
    }

    #Add Button event 
    $Button.Add_Click({    
        [System.Windows.Forms.MessageBox]::Show($Button.Text , "My Dialog Box")
    })

    $Form.Controls.Add($Button)

}

    #Show the Form 
    $form.ShowDialog()| Out-Null 

} #End Function 


Generate-Form;

2 Comments

updated $Button object initialization like VB style
Thank you. This is an interesting solution.

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.