关闭事件处理程序 C#

Posted

技术标签:

【中文标题】关闭事件处理程序 C#【英文标题】:Closing event handlers C# 【发布时间】:2012-11-25 15:28:04 【问题描述】:

我有两个表单,表单 2 继承自表单 1。

我需要做的是,当我关闭表格 1 和表格 2 时,会出现另一个询问用户是否确定要退出的表格。然后,如果用户单击“是”,当且仅当用户关闭的表单是表单 2 而不是表单 1 时,会出现另一个询问用户是否要保存游戏的表单,因为对于表单 1,不需要保存。

这是我设法做到的:

// 这些是 Form 1 的关闭和关闭事件处理程序:

private void GameForm_FormClosing(object sender, FormClosingEventArgs e)

    e.Cancel = true;
    SureClose sc = new SureClose();
    sc.StartPosition = FormStartPosition.CenterScreen;
    sc.Show();


private void GameForm_FormClosed(object sender, FormClosedEventArgs e)

    MainMenu menu = new MainMenu();
    menu.Show();

然后在 Sure Close: // 请注意 Tournament 是 Form 2 继承自 GameForm (Form 1)

 private void yesButton_Click(object sender, EventArgs e)
 
        this.Hide();

        if (GameForm.ActiveForm is Tournament)
        
            SaveGame sg = new SaveGame();
            sg.StartPosition = FormStartPosition.CenterScreen;
            sg.Show();
         
        else 
        
            GameForm.ActiveForm.Close();
        
    

    private void noButton_Click(object sender, EventArgs e)
    
        this.Hide();
    

// 这是保存游戏表单:

 private void saveButton_Click(object sender, EventArgs e)
 
     // Still to do saving!
 

 private void dontSaveButton_Click(object sender, EventArgs e)
 
     this.Hide();
     GameForm.ActiveForm.Close();
 

问题是,当在 SureClose Form 中的 yesButton 事件处理程序中,我有 GameForm.ActiveForm.Close(),这将返回到 GameForm Closing 事件处理程序,因此 SureClose 对话框再次出现。

我尝试过这样做: if (e.CloseReason() == CloseReason.UserClosing) 但显然它也不起作用,因为关闭的原因永远是用户:/

我该如何解决这个问题? 非常感谢您的帮助!

【问题讨论】:

GameForm_FormClosing 中,您可以使用带有yes / no 的消息框。然后使用对话结果对结果使用不同的操作。有关示例,请参见 this link。 为什么对话框而不是另一个表单会有所作为? 看看德米特里的回答。它允许您留在同一个方法中,而不必去另一个类并再次调用前一个方法(这当然是递归的),并且从 form1 中的虚拟覆盖可以看出它不会做任何事情,而在 form2 它要求保存游戏。 【参考方案1】:

表格1:

private void GameForm_FormClosing(object sender, FormClosingEventArgs e)

    if(SureClose())
    
        SaveChanges();
    
    else
    
        e.Cancel = true; 
    


private bool SureClose()

    using(SureClose sc = new SureClose())
    
        sc.StartPosition = FormStartPosition.CenterScreen;
        DialogResult result = sc.ShowDialog();
        if(result == DialogResult.OK)
        
            return true;
        
        else
        
            return false;
        
    


protected virtual void SaveChanges()


表格2:

protected override void SaveChanges()

    using(SaveGame sg = new SaveGame())
    
        sg.StartPosition = FormStartPosition.CenterScreen;
        DialogResult result = sg.ShowDialog();
        if(result == DialogResult.OK)
        
            //saving code here
        
    

SureClose 表单和 SaveGame 表单:

private void yesButton_Click(object sender, EventArgs e)

    this.DialogResult = DialogResult.OK;


private void noButton_Click(object sender, EventArgs e)

    this.DialogResult = DialogResult.Cancel;

【讨论】:

感谢您的帮助,德米特里! DialogResult 结果 = sg.Show(); --- 这将返回一个错误 - 无法将类型 void 隐式转换为 DialogResult 并且这似乎在 Form 2 中不存在:saveButton_Click(null, null); 是的。我的错。您应该使用 ShowDialog() 并且您应该更改 SaveGame 和 SureClose 表单,以便在按下右键时它们将返回 DialogResult.OK 但是事件处理程序不能返回任何东西,不是吗? :/ 抱歉,我是新手! 在表单中设置 this.DialogResult 时,通过 ShowDialog() 方法打开,表单关闭,返回原始码 if(result == DialogResult.OK) return true; else return false; 可以简写为return result == DialogResult.OK

以上是关于关闭事件处理程序 C#的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Windows 和 Linux 系统上使用 Avalonia 框架处理系统关闭事件?

了解 C# 中的事件和事件处理程序

不使用Dispose事件处理程序处理应用程序关闭事件

在没有 Dispose 事件处理程序的情况下处理应用程序关闭事件

C# 事件处理程序委托中的闭包? [复制]

在 C# 中使用弱处理程序引发 PropertyChanged 事件时发生 ExecutionEngineException