Могу ли я создать / объявить несколько объектов PowerShell одного и того же типа одновременно? - PullRequest
0 голосов
/ 01 марта 2019

У меня есть форма 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:

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

... и т. д.

Есть ли способ создания нескольких объектов одного и того же типа с инкрементным суффиксом все за один раз?вместо того, чтобы объявлять их по отдельности, или я застрял, написав их так, как я их получил в настоящее время?

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

This ...

$label1, $label2, $label3 = New-Object System.Windows.Forms.Label

... создает новый Label и присваивает его $label1.Ничего не назначено $label2 и $label3, потому что справа нет значений для них.Если бы этот синтаксис назначил все три переменные, они (вероятно) все содержали бы один и тот же экземпляр Label, который в любом случае не работал бы для вашего варианта использования.

Вместо этого, чтобы создать три экземпляра Label иназначьте их трем переменным, которые вам понадобятся для этого ...

$label1, $label2, $label3 = (New-Object System.Windows.Forms.Label), (New-Object System.Windows.Forms.Label), (New-Object System.Windows.Forms.Label)

... который можно упростить до ...

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

... который можетбыть упрощенным до ...

$label1, $label2, $label3 = 1..3 | % { New-Object System.Windows.Forms.Label }
0 голосов
/ 01 марта 2019

Множественное присваивание присваивает элементы массива справа от присваивания переменным слева.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 ...))

Обратите внимание, что вам нужно группировать выражения вокруг вызовов функций, когда их помещают в вызовы методов.Отсюда два набора скобок.

Конечно, New-Label может быть улучшен еще больше, например, с помощью целочисленных массивов вместо строк для $Location и $Size.Или путем установки другого параметра с индивидуальными значениями для $Top, $Left, $Width и $Height и назначением значений в зависимости от того, какой набор параметров используется.Параметры также должны быть проверены.И так далее, и так далее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...