我可以一次创建/声明几个相同类型的PowerShell对象吗?

Tyl*_*erH 4 powershell

我有各种套一个PowerShell(版本5.1)形式System.Windows.Forms在它的对象都命名为通用的东西,比如$label1,$label2等还有$textBox1,$textBox2等等.

目前,我正在创建它们,因为它们出现在表单中,如下所示:

Add-Type -AssemblyName System.Windows.Forms

$Form = New-Object system.Windows.Forms.Form
$Form | ForEach-Object {
    $_.Size = New-Object System.Drawing.Size(800,550)
    $_.StartPosition = 'CenterScreen'
    $_.Text = "Example Form Name"
    $_.Topmost = $true
}

$label1 = New-Object System.Windows.Forms.Label
$label1 | ForEach-Object {
    $_.Location = '10,10'
    $_.Size = '156,20'
    $_.Text = 'Dummy text part 1'
}

$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1 | ForEach-Object {
    $_.Location = '166,8'
    $_.Size = '100,20'
}

$label2 = New-Object System.Windows.Forms.Label
$label2 | ForEach-Object {
    $_.Location = '267, 10'
    $_.Size = '85,20'
    $_.Text = 'Dummy text part 2'
}

$textBox2 = New-Object System.Windows.Forms.TextBox
$textBox2 | ForEach-Object {
    $_.Location = '352,8'
    $_.Size = '100,20'
}

#A lot more lines of similar code go here

$Form.Controls.Add($label1)
$Form.Controls.Add($textBox1)
$Form.Controls.Add($label2)
$Form.Controls.Add($textBox2)

$result = $Form.ShowDialog()
Run Code Online (Sandbox Code Playgroud)

我根据这个方案创建并命名了几十个这些对象,我真的想通过在每一行上创建所有这些来保存一些行(例如,所有labels在一行上,然后所有textBoxes在一行上),或至少在一个方法/函数中.

我试过这个:

$label1, $label2, $label3 = New-Object System.Windows.Forms.Label
Run Code Online (Sandbox Code Playgroud)

而不是$label在上面的完整演示形式中单独声明每个,但PowerShell似乎没有那样工作; 它仅创建$label1(这本身是奇数;我会一直,预计仅创建$label3了它去上班的只是其中之一)和PowerShell ISE后来就抛出一个错误的属性的声明$label2$label3:

The property 'Location' cannot be found on this object. Verify that the property exists and can be set. 
At <filepath>.ps1:43 char:5
+     $_.Location = '267, 10'
+     ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

...等等.

有没有一种方法可以创建多个相同类型的Object,并且一次性使用递增后缀,而不是每个都在自己的行上声明它们,或者我是不是写了这些我现在如何得到它们?

Ans*_*ers 6

多项赋值将赋值右侧的数组元素分配给左侧的变量.New-Objectin and of本身不允许一次创建多个对象.您可以编写一个循环或一个生成标签数组的函数,然后使用多个赋值将该数组的元素分配给变量.

$label1, $label2, $label3 = 1..3 | ForEach-Object {
    New-Object Windows.Forms.Label
}
Run Code Online (Sandbox Code Playgroud)

要么

function New-Label {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$false)]
        [int]$Count = 1
    )

    for ($i=0; $i -lt $count; $i++) {
        New-Object Windows.Forms.Label
    }
}

$label1, $label2, $label3 = New-Label 3
Run Code Online (Sandbox Code Playgroud)

但是,我认为更好的方法是编写一个函数来创建一个带有给定参数的标签对象,然后将该函数的输出分配给一个变量.

function New-Label {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [string]$Location,
        [Parameter(Mandatory=$true)]
        [string]$Size,
        [Parameter(Mandatory=$false)]
        [string]$Text = ''
    )

    $o = New-Object Windows.Forms.Label
    $o.Location = $Location
    $o.Size     = $Size
    $o.Text     = $Text

    return $o
}

$label1 = New-Label -Location '10,10' -Size '156,20' -Text 'Dummy text part 1'
$label2 = New-Label -Location '267,10' -Size '85,20' -Text 'Dummy text part 2'
$label3 = ...
Run Code Online (Sandbox Code Playgroud)

您也可以直接将标签添加到表单中,而不是先将它们分配给变量:

$Form.Controls.Add((New-Label '10,10' '156,20' 'Dummy text part 1'))
$Form.Controls.Add((New-Label '267,10' '85,20' 'Dummy text part 2'))
$Form.Controls.Add((New-Label ...))
Run Code Online (Sandbox Code Playgroud)

请注意,当将它们matrjoshking(嵌套)到方法调用中时,需要围绕函数调用对表达式进行分组.因此两套括号.

当然,New-Label可以进一步改进,例如通过使用整数数组而不是字符串for $Location$Size.或通过具有另一个参数与单个数值设置$Top,$Left,$Width,和$Height,并分配根据哪个参数组所使用的值.参数也应该被验证.等等等等.