kpogue 的有用答案很好地解释了您的问题,并提供了一个有效的解决方案,但由于依赖于全局变量而不是最佳的。
让我建议一种不同的方法,您使用一个函数来简单地定义表单并返回该定义,您可以根据需要在其上调用.Show()
和.Close()
方法,但请注意,该.Show()
方法被覆盖 viaAdd-Member
以包含对 的调用[System.Windows.Forms.Application]::DoEvents()
,以便确保正确绘制表格。
function New-PopUpForm {
Add-Type -AssemblyName System.Windows.Forms
# Create the form.
$objForm = New-Object System.Windows.Forms.Form -Property @{
Text = "Test"
Size = New-Object System.Drawing.Size 220, 100
StartPosition = 'CenterScreen' # Center on screen.
FormBorderStyle = 'FixedSingle' # fixed-size form
# Remove interaction elements (close button, system menu).
ControlBox = $false
}
# Create a label...
$objLabel = New-Object System.Windows.Forms.Label -Property @{
Location = New-Object System.Drawing.Size 80, 20
Size = New-Object System.Drawing.Size 100, 20
Text = "Hi there!"
}
# ... and add it to the form.
$objForm.Controls.Add($objLabel)
# Override the `.Show()` method to include
# a [System.Windows.Forms.Application]::DoEvents(), so as
# to ensure that the form is properly drawn.
$objForm | Add-Member -Force -Name Show -MemberType ScriptMethod -Value {
$this.psbase.Show() # Call the original .Show() method.
# Activate the form (focus it).
$this.Activate()
[System.Windows.Forms.Application]::DoEvents() # Ensure proper drawing.
}
# Since this form is meant to be called with .Show() but without
# a [System.Windows.Forms.Application]::DoEvents() *loop*, it
# it is best to simply *hide* the cursor (mouse pointer), so as not
# to falsely suggest that interaction with the form is possible
# and so as not to end up with a stuck "wait" cursor (mouse pointer) on
# the first instantiation in a session.
[System.Windows.Forms.Cursor]::Hide()
# Return the form.
return $objForm
}
然后,您可以按如下方式使用该功能:
$form = New-PopupForm
$form.Show()
# ...
$form.Close()
注意:
注意事项:
请注意,由于使用了该.Show()
方法(无需额外的努力),用户将无法与弹出窗口进行交互,尤其是甚至无法 移动窗口或手动关闭它。
- 如果,例如在您的情况下,该窗口不打算与之交互,那么这不是问题。
- 上面的设置
ControlBox = $false
去掉了窗口的关闭按钮和系统菜单,从而明显的无法交互。
- 隐藏光标(鼠标指针)具有
[System.Windows.Forms.Cursor]::Hide()
相同的目的。
- 注意:不隐藏光标会导致在将鼠标悬停在表单上时无限期地显示“等待”光标(表明表单正忙于处理某些内容),但奇怪的是仅针对会话中创建的第一个实例。我知道的唯一避免它的方法是在调用之后进入事件循环
.Show()
,如最后一个要点中所述。
相比之下,.ShowDialog()
将允许交互,但会阻止脚本的进一步执行,直到用户关闭窗口。
如果您需要结合这两种方法 -允许用户与窗口交互,同时继续在您的 PowerShell 脚本中进行处理- 您需要循环调用[System.Windows.Forms.Application]::DoEvents()
,如本答案所示。
- 如果您使用这种方法,您应该
[System.Windows.Forms.Cursor]::Hide()
从函数中删除调用。