The correctness of creating objects using a loop

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

Upvotes: 1

Views: 84

Answers (2)

Kundan
Kundan

Reputation: 1415

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;

Upvotes: 1

mklement0
mklement0

Reputation: 437823

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.

Upvotes: 1

Related Questions