如何在应用程序关闭前显示未保存的更改对话框?
How do I show an unsaved changes dialog box before application closing?
我有一个 C# Windows 表单应用程序
我想在应用程序关闭前显示一个 "There are unsaved changes. Save/Quit/Cancel" 样式的确认对话框。也可能同时防止应用程序关闭。我该怎么做?
此外,如果应用程序未关闭,Windows 10 上的关闭进程会发生什么情况?
取决于显示技术(WPF/UWP 或 WinForms),但通常每个表单都有一个 "Closing" 事件。您可以在哪里显示 MessageBox 甚至取消表单关闭。
它们都是 class 的基本 Form/Windows:
https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.form.closing
https://docs.microsoft.com/en-us/dotnet/api/system.windows.window.closing
应用程序本身只会在所有表单 关闭后关闭(这可能包括隐藏的),因此这将防止应用程序关闭。但是单独的表单如果不反抗的话还是有可能被关闭的。
如果您的应用程序不会关闭并且用户没有选择 "Force Close",Windows 的关闭进程最终将停止并出现静默失败。然而,这被认为是不良行为。确实有几次我以为它已经重启了,但实际上关机是因为某人而停止的。
特别是磁盘操作可能会导致应用程序关闭时出现相关停顿。许多文字处理器处理隐藏的临时文件以进行崩溃恢复。因此,如果用户不响应,则始终可以默认将状态写在那里。
您可以像这样使用 FormClosing
事件:
private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
{
if ( ThereAreUnsavedChanges )
switch ( MessageBox.Show("Message",
Text,
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question) )
{
case DialogResult.Yes:
DoSave();
break;
case DialogResult.No:
break;
case DialogResult.Cancel:
e.Cancel = true;
break;
}
}
您可以使用自定义表单代替消息框:
private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
{
if ( ThereAreUnsavedChanges )
switch ( new SaveDataQueryBox().ShowDialog() )
{
case DialogResult.Yes:
DoSave();
break;
case DialogResult.No:
break;
case DialogResult.Cancel:
e.Cancel = true;
break;
}
}
在此表格中,您将根据用户选择分配 DialogResult
属性。
在按钮保存点击事件中:
DialogResult = DialogResult.Ok;
Close();
在按钮退出点击事件中:
DialogResult = DialogResult.No;
Close();
在按钮取消点击事件中:
DialogResult = DialogResult.Cancel;
Close();
对于结束会话,可以在InitializeComponents
之后的构造函数中添加:
SystemEvents.SessionEnding += SessionEnding;
加入class:
private bool IsSessionEnding;
private void SessionEnding(object sender, SessionEndingEventArgs e)
{
IsSessionEnding = true;
Close();
}
因此 FormClosing
将是:
private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
{
if ( IsSessionEnding)
// Decide if you want to auto save or not
else
if ( ThereAreUnsavedChanges )
switch ( MessageBox.Show("Message",
Text,
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question) )
{
case DialogResult.Yes:
DoSave();
break;
case DialogResult.No:
break;
case DialogResult.Cancel:
IsSessionEnding = false;
e.Cancel = true;
break;
}
}
如果您不这样做,当会话结束时,系统会提示用户并且操作系统会阻塞,看到一个应用程序无响应的消息框,除非它被设置为强制进程终止。
要确保关闭所有表单,您可以使用此方法:
private void CloseForms()
{
foreach ( Form form in Application.OpenForms )
if ( form != this && form.Visible )
try
{
form.Close();
}
catch
{
}
}
例如,您可以从 FormClosed 事件调用它。
我有一个 C# Windows 表单应用程序
我想在应用程序关闭前显示一个 "There are unsaved changes. Save/Quit/Cancel" 样式的确认对话框。也可能同时防止应用程序关闭。我该怎么做?
此外,如果应用程序未关闭,Windows 10 上的关闭进程会发生什么情况?
取决于显示技术(WPF/UWP 或 WinForms),但通常每个表单都有一个 "Closing" 事件。您可以在哪里显示 MessageBox 甚至取消表单关闭。
它们都是 class 的基本 Form/Windows:
https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.form.closing
https://docs.microsoft.com/en-us/dotnet/api/system.windows.window.closing
应用程序本身只会在所有表单 关闭后关闭(这可能包括隐藏的),因此这将防止应用程序关闭。但是单独的表单如果不反抗的话还是有可能被关闭的。
如果您的应用程序不会关闭并且用户没有选择 "Force Close",Windows 的关闭进程最终将停止并出现静默失败。然而,这被认为是不良行为。确实有几次我以为它已经重启了,但实际上关机是因为某人而停止的。
特别是磁盘操作可能会导致应用程序关闭时出现相关停顿。许多文字处理器处理隐藏的临时文件以进行崩溃恢复。因此,如果用户不响应,则始终可以默认将状态写在那里。
您可以像这样使用 FormClosing
事件:
private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
{
if ( ThereAreUnsavedChanges )
switch ( MessageBox.Show("Message",
Text,
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question) )
{
case DialogResult.Yes:
DoSave();
break;
case DialogResult.No:
break;
case DialogResult.Cancel:
e.Cancel = true;
break;
}
}
您可以使用自定义表单代替消息框:
private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
{
if ( ThereAreUnsavedChanges )
switch ( new SaveDataQueryBox().ShowDialog() )
{
case DialogResult.Yes:
DoSave();
break;
case DialogResult.No:
break;
case DialogResult.Cancel:
e.Cancel = true;
break;
}
}
在此表格中,您将根据用户选择分配 DialogResult
属性。
在按钮保存点击事件中:
DialogResult = DialogResult.Ok; Close();
在按钮退出点击事件中:
DialogResult = DialogResult.No; Close();
在按钮取消点击事件中:
DialogResult = DialogResult.Cancel; Close();
对于结束会话,可以在InitializeComponents
之后的构造函数中添加:
SystemEvents.SessionEnding += SessionEnding;
加入class:
private bool IsSessionEnding;
private void SessionEnding(object sender, SessionEndingEventArgs e)
{
IsSessionEnding = true;
Close();
}
因此 FormClosing
将是:
private void FormTest_FormClosing(object sender, FormClosingEventArgs e)
{
if ( IsSessionEnding)
// Decide if you want to auto save or not
else
if ( ThereAreUnsavedChanges )
switch ( MessageBox.Show("Message",
Text,
MessageBoxButtons.YesNoCancel,
MessageBoxIcon.Question) )
{
case DialogResult.Yes:
DoSave();
break;
case DialogResult.No:
break;
case DialogResult.Cancel:
IsSessionEnding = false;
e.Cancel = true;
break;
}
}
如果您不这样做,当会话结束时,系统会提示用户并且操作系统会阻塞,看到一个应用程序无响应的消息框,除非它被设置为强制进程终止。
要确保关闭所有表单,您可以使用此方法:
private void CloseForms()
{
foreach ( Form form in Application.OpenForms )
if ( form != this && form.Visible )
try
{
form.Close();
}
catch
{
}
}
例如,您可以从 FormClosed 事件调用它。