Почему ваш оригинальный фрагмент работает и почему ваш связанный с ним полный сценарий не работа описана в моем ответе на ваш связанный вопрос .
Короче говоря: у вас был обработчик событий, который вызвал вашу Submit
функцию без аргументов сначала, в добавление к , позже вызвав его правильно с аргументом , что вызвало проблему.
Что касается объяснения в ваш собственный ответ :
Ваш переставленный код работает только случайно :
Он присоединяет обработчик событий, содержащий некорректный, без аргументов Submit
вызов после отображения диалогового окна, после чего он просто ничего не делает.
Как структурировать ваш код:
У вас есть два основных варианта, которые обычно объединяются :
Принять меры во время отображения диалогового окна , используя обработчики событий .
Вы присоединяете обработчики событий как блоки сценариев, передаваемые в методы .Add_<eventName>()
отдельных элементов управления, как вы это делали в случае $btnSubmit.Add_Click({ ... })
.
Предупреждение: блок сценария выполняется в области дочерних переменных , поэтому требуется дополнительная работа для изменения переменных в области действия вызывающего, например, с помощью спецификатора области script
; например, $script:var
(или даже с использованием подхода [ref]
, но это жестко).
Принять меры после закрытия диалога .
- После этого вы можете просто напрямую получить доступ к свойствам элементов управления формы.
Следующий автономный фрагмент демонстрирует обе техники:
Add-Type -AssemblyName System.Windows.Forms
# Create the form.
$form = New-Object system.Windows.Forms.Form -Property @{
ClientSize = New-Object System.Drawing.Point 400,100
Text = "Dialog Demo"
}
# Create the controls and add them to the form.
$form.Controls.AddRange(@(
New-Object system.Windows.Forms.Label -Property @{
Text = "First Name:"
AutoSize = $true
Location = New-Object System.Drawing.Point 10,20
Font = 'Microsoft Sans Serif,10'
}
($txtFirstName = New-Object system.Windows.Forms.TextBox -Property @{
Width = 250
Location = New-Object System.Drawing.Point 100, 20
})
($btnSubmit = New-Object system.Windows.Forms.Button -Property @{
Text = "Submit"
Location = New-Object System.Drawing.Point 160, 60
})
))
# Attach an event handler to the first-name field.
$txtFirstName.Add_KeyPress({ param($obj, $evArgs)
# Example: Convert every character typed to uppercase.
$evArgs.KeyChar = [char]::ToUpper($evArgs.KeyChar)
})
# Make pressing Enter the same as clicking the Submit button.
$form.AcceptButton = $btnSubmit
# Make the Submit button act like an OK button, which means:
# - auto-close the form
# - make .ShowDialog() return [System.Windows.Forms.DialogResult]::OK
$btnSubmit.DialogResult = [System.Windows.Forms.DialogResult]::OK
# Show the form synchronously (during which event handlers may fire)
# and take action based on the return value, which is
# a [System.Windows.Forms.DialogResult] enumeration value that
# reflects the button used to close the form.
if ($form.ShowDialog() -eq 'OK') { # Dialog was confirmed.
# You can now access the controls' properties as needed.
# In this example we output a custom object that contains
# the first name; this can easily be extended to include
# other properties
[pscustomobject] @{
FirstName = $txtFirstName.Text
}
} else { # Dialog was canceled.
Write-Warning "Dialog canceled."
}