The FormClosing
event argument object's .CloseReason
property doesn't allow you to distinguish between the .Close()
method having been called on the form and the user closing the form via the title bar / window system menu / pressing Alt+F4 - all these cases equally result in the .CloseReason
property reflecting enumeration value UserClosing
.
However, you can adapt the technique from Reza Aghaei's helpful C# answer on the subject, by inspecting the call stack for a call to a .Close()
method:
using assembly System.Windows.Forms
using namespace System.Windows.Forms
using namespace System.Drawing
# Create a sample form.
$form = [Form] @{
ClientSize = [Point]::new(400,100)
Text = 'Closing Demo'
}
# Create a button and add it to the form.
$form.Controls.AddRange(@(
($btnClose = [Button] @{
Text = 'Close'
Location = [Point]::new(160, 60)
})
))
# Make the button call $form.Close() when clicked.
$btnClose.add_Click({
$form.Close()
})
# The event handler called when the form is closing.
$form.add_Closing({
# Look for a call to a `.Close()` method on the call stack.
if ([System.Diagnostics.StackTrace]::new().GetFrames().GetMethod().Name -ccontains 'Close') {
Write-Host 'Closed with .Close() method.'
} else {
Write-Host 'Closed via title bar / Alt+F4.'
}
})
$null = $form.ShowDialog() # Show the form modally.
$form.Dispose() # Dispose of the form.
If you run this code and try various methods of closing the form, a message indicating the method used should print (.Close()
call vs. title bar / Alt+F4).
Note:
Closing the form via buttons assigned to the form's .CancelButton
and .SubmitButton
properties that don't have explicit $form.Close()
calls still causes .Close()
to be called behind the scenes.
The code requires PowerShell v5+, but it can be adapted to earlier versions.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…