如何在应用程序关闭之前显示未保存的更改对话框? [关闭]

Posted

技术标签:

【中文标题】如何在应用程序关闭之前显示未保存的更改对话框? [关闭]【英文标题】:How do I show an unsaved changes dialog box before application closing? [closed] 【发布时间】:2019-11-10 18:19:43 【问题描述】:

我有一个 C# Windows 窗体应用程序

我想在应用程序关闭之前显示“有未保存的更改。保存/退出/取消”样式确认对话框。还可能同时防止应用程序关闭。我该怎么做?

此外,如果应用程序没有关闭,Windows 10 上的关闭过程会发生什么?

【问题讨论】:

哪个关机按钮?你试过什么?源代码在哪里? 关闭时,操作系统会向所有应用程序发送关闭信号。只需监听应用程序的关闭事件。 他只想要一个“有未保存的更改。保存/退出/取消”对话框。没有什么特别或奇怪的。 【参考方案1】:

您可以像这样使用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;

在类中添加:

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 事件中调用它。

【讨论】:

【参考方案2】:

取决于显示技术(WPF/UWP 或 WinForms),但每个表单通常都有一个“关闭”事件。您可以在哪里显示该 MessageBox 甚至取消表单关闭。

它们都属于 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

应用程序本身只会在所有表单关闭后关闭(这可能包括隐藏的表单),因此这将阻止应用程序关闭。但是,如果它们不抵抗,单独的表单可能仍会关闭。

如果您的应用程序不会关闭并且用户没有选择“强制关闭”,Windows 的关闭过程最终将停止并出现无提示的失败。但是,这被认为是不良行为。确实有几次我以为它已经重新启动了,但实际上关闭是因为有人而停止了。

特别是磁盘操作可能会导致应用程序关闭时出现相关停顿。许多文字处理器处理隐藏的临时文件以进行崩溃恢复。因此,如果用户不回复,则始终可以默认将状态写入那里。

【讨论】:

以上是关于如何在应用程序关闭之前显示未保存的更改对话框? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在 SessionStorage 中未保存更改时警告用户

在离开网页之前警告用户未保存的更改角度

Angular:在关闭浏览器窗口之前显示材质弹出窗口

FileSaveDialog - 未完全显示文件名文本

如何在离开页面之前警告用户未保存的表单更改? - 角度 6

Facebook 如何在其应用程序中为未保存的更改显示自定义模式窗口?