Это может быть немного «умным» решением, а не «простым для понимания и поддержки» решением, но я все равно добавил его, потому что оно использует то, о чем я не знал до того, как начал изучать этот ответ - то есть метод ScriptBlock.GetNewClosure :
Add-Type -assembly System.Windows.Forms
function New-Label
{
param($LabelNum, $LabelText)
$label = New-Object System.Windows.Forms.Label
$label.Name = "Label_$LabelNum"
$label.Text = $LabelText
$LabelY = 1 + $LabelNum * 50
$label.Location = New-Object System.Drawing.Point(10, $LabelY)
return $label
}
function New-Button
{
param($ButtonNum, $ButtonText)
$button = New-Object System.Windows.Forms.Button
$button.Text = $ButtonText
$ButtonY = 1 + $ButtonNum * 50
$button.Location = New-Object System.Drawing.Point(150, $ButtonY)
return $button
}
function New-Form
{
$form = New-Object System.Windows.Forms.Form
$form.Text = "Test1"
$form.Width = 250
$form.Height = 250
# create an array of labels
$labels = 0..3 | % {
New-Label -LabelNum $_ -LabelText "label_$($_)"
}
# add the labels to the form
$labels | % { $form.Controls.Add($_) }
# create an array of buttons
$buttons = 0..3 | % {
New-Button -ButtonNum $_ -ButtonText "button_$($_)"
}
# add the buttons to the form
$buttons | % { $form.Controls.Add($_) }
# add event handlers onto the buttons
for( $i = 0; $i -lt $buttons.Length; $i++ )
{
$buttons[$i].Add_Click(
{ $labels[$i].Text = $buttons[$i].Text }.GetNewClosure()
)
}
return $form
}
$main_form = New-Form
$main_form.ShowDialog()
Я сделал несколько вещей, которые (на мой взгляд) упрощают ваш код, удаляя ссылки на глобальные переменные внутри функций. Вместо того, чтобы добавлять метки и кнопки к самим $main_form
функциям, они просто возвращают независимую метку или кнопку и позволяют вызывающему коду принять решение об их использовании.
«Умный» (но, возможно, не такой «умный») ") бит использует GetNewClosure
в New-Form
- сначала мы создаем параллельные массивы меток и кнопок, а затем объединяем их вместе, чтобы создать обработчики событий.
Это дает то преимущество, что вам не нужно снова «найти» метки и кнопки по имени после их создания, потому что вы храните ссылки на них в массивах, но у него есть недостаток в том, что он использует GetNewClosure
, что нелегко объяснить, что он на самом деле делает!
Я думаю, что ответ Тео может быть более прагматичным c, но вот несколько ссылок на документацию для GetNewEnclosure
на тот случай, если вы захотите прочитать об этом ...
Надеюсь, это поможет ...