Я изучил новый метод PowerShell пару дней go - GetNewClosure()
- и с тех пор это уже третий вопрос, на который я ответил, который его использует: -).
* 1003 Во-первых, я немного упростил ваш код, потому что вам не нужно хранить ссылки на все ваши элементы управления в глобальном массиве. Затем я также добавил вызов к
GetNewClosure()
в ваши скриптовые блоки обратного вызова.
(упрощенный) код:
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Width = 985
$Form.Height = 560
$TabBox = New-object System.Windows.Forms.TabControl
$TabBox.Location = New-Object System.Drawing.size(5,5)
$TabBox.Dock = "Fill"
$Form.Controls.Add($TabBox)
foreach ($item in @("page1", "page2", "page3") )
{
#### tab page
$tabPage = New-Object System.Windows.Forms.TabPage
$tabPage.DataBindings.DefaultDataSourceUpdateMode = 0
$tabPage.Text = $item
$tabBox.Controls.Add($tabPage)
#### disabled listbox
$disabledList = New-Object system.Windows.Forms.ListBox
$disabledList.location = New-Object System.Drawing.Point(10,30)
$disabledList.width = 395
$disabledList.height = 440
$disabledList.SelectionMode = 'MultiExtended'
@( "aaa", "bbb" ) | % { $disabledList.Items.Add($_) }
$tabPage.Controls.Add($disabledList)
#### enabled listbox
$enabledList = New-Object system.Windows.Forms.ListBox
$enabledList.location = New-Object System.Drawing.Point(540,30)
$enabledList.width = 395
$enabledList.height = 440
$enabledList.SelectionMode = 'MultiExtended'
@( "ccc", "ddd" ) | % { $enabledList.Items.Add($_) }
$tabPage.Controls.Add($enabledList)
#### add button
$addButton = New-Object system.Windows.Forms.Button
$addButton.location = New-Object System.Drawing.Point(440,140)
$addButton.text = "-->"
$addButton.width = 70
$addButton.height = 30
$tabPage.Controls.Add($addButton)
$addButton.Add_Click(
{
@( $disabledList.SelectedItems ) | Foreach {
$enabledList.Items.Add($_)
$disabledList.Items.Remove($_)
}
}.GetNewClosure()
)
#### remove button
$removeButton = New-Object system.Windows.Forms.Button
$removeButton.location = New-Object System.Drawing.Point(440,185)
$removeButton.text = "<--"
$removeButton.width = 70
$removeButton.height = 30
$removeButton.Add_Click(
{
@( $enabledList.SelectedItems ) | Foreach {
$disabledList.Items.Add($_)
$enabledList.Items.Remove($_)
}
}.GetNewClosure()
)
$tabPage.Controls.Add($removeButton)
####OkButton
$OkButton = New-Object system.Windows.Forms.Button
$OkButton.location = New-Object System.Drawing.Point(440,230)
$OkButton.text = "Ok"
$OkButton.width = 70
$OkButton.height = 30
$OkButton.Add_Click({OkClick})
$tabPage.Controls.Add($OkButton)
####CancelButton
$CancelButton = New-Object system.Windows.Forms.Button
$CancelButton.location = New-Object System.Drawing.Point(440,275)
$CancelButton.text = "Cancel"
$CancelButton.width = 70
$CancelButton.height = 30
$CancelButton.Font = 'Microsoft Sans Serif,10'
$CancelButton.Add_Click({CancelClick})
$tabPage.Controls.Add($CancelButton)
}
function OkClick {
$Form.Close()
}
function CancelClick {
$Form.Close()
}
[void]$Form.ShowDialog()
Короче говоря, ваши исходные обратные вызовы вычисляли выражение $_HashFormTabTable[$_Computer].PotentialBox
, например, во время выполнения обратного вызова , а не при создании сценария обратного вызова создания .
Обратите внимание, что PowerShell сохраняет последнее значение итератора переменная при выходе foreach
l oop - например,
PS> foreach ($x in @("aaa", "bbb", "ccc") ) {}
PS> $x
ccc
, поэтому, когда любой ваших обратных вызовов выполнялся, они все получали последний элемент в массиве $_HashFormTabTable
потому что значение $_Computer
было последним значением, итерированным в for для l oop.
Сравните поведение этого скрипта, например:
$callbacks = @();
foreach( $item in @( "aaa", "bbb", "ccc" ) )
{
$callbacks += { write-host "callback = '$item'" }
}
write-host "item = '$item'";
foreach( $callback in $callbacks )
{
$callback.Invoke()
}
, который выводит
item = 'ccc'
callback = 'ccc'
callback = 'ccc'
callback = 'ccc'
с этим:
$callbacks = @();
foreach( $item in @( "aaa", "bbb", "ccc" ) )
{
$callbacks += { write-host "callback = '$item'" }.GetNewClosure()
}
write-host "item = '$item'"
foreach( $callback in $callbacks )
{
$callback.Invoke()
}
, который выводит:
item = 'ccc'
callback = 'aaa'
callback = 'bbb'
callback = 'ccc'
Надеюсь, это поможет.