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

标签 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()

我已经根据该方案创建和命名了几十个这些对象,我真的很想通过在一行中创建所有这些对象来节省一些行(例如,一行中的所有label,然后将所有textBox都放在一行上),或者至少每种使用一种方法/函数。

我尝试了这个:
$label1, $label2, $label3 = New-Object System.Windows.Forms.Label

而不是在上面完整的演示表单中声明每个$label自己的一行,但是PowerShell似乎无法像这样工作;它仅创建$label1(这本身很奇怪;我希望它仅能在其中一个上工作才创建$label3),而PowerShell ISE稍后为$label2$label3的属性声明引发错误:

在此对象上找不到属性“Location”。验证该属性存在并且可以设置。
.ps1:43 char:5
+ $ _。Location ='267,10'
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo:InvalidOperation:(:) [],RuntimeException
+ FullyQualifiedErrorId:PropertyNotFound

...等等。

有没有一种方法可以一次性创建多个具有递增后缀的相同类型的Object,而不是将它们各自声明在自己的行上,或者是我坚持写这些文件的方式?

最佳答案

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

$label1, $label2, $label3 = 1..3 | ForEach-Object {
    New-Object Windows.Forms.Label
}

要么
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

但是,我认为一种更好的方法是编写一个函数,用给定的参数创建一个标签对象,然后将该函数的输出分配给一个变量。
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 = ...

您也可以直接将标签添加到表单中,而不是先将它们分配给变量:
$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 ...))

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

当然,可以进一步改善New-Label,例如通过使用整数数组代替$Location$Size的字符串。或者通过设置另一个参数来设置$Top$Left$Width$Height的各个值,然后根据所使用的参数集来分配值。参数也应验证。等等等等。

关于powershell - 我可以一次创建/声明多个相同类型的PowerShell对象吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54934494/

相关文章:

powershell - 找不到与参数名称 'TokenKind' 匹配的参数

windows - Powershell ISE 崩溃时在哪里存储选项卡?

powershell - 如何使用PowerShell远程检查Web应用程序池的状态?

powershell - 如何使用相对路径调用另一个 PowerShell 脚本?

Powershell:使用 try and catch 进行错误处理

windows - PowerShell session 中的字符编码 (UTF-8)

regex - 正则表达式以验证Powershell中特定格式的字符串

csv - 从Powershell foreach循环将输出安排为CSV

powershell - powershell-创建动态打印机脚本-输出和命令结构

PowerShell:比较日期