Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Windows窗体中关闭模式窗体的计时器_C#_Winforms_Timer - Fatal编程技术网

C# 在Windows窗体中关闭模式窗体的计时器

C# 在Windows窗体中关闭模式窗体的计时器,c#,winforms,timer,C#,Winforms,Timer,我有几个带有网格的无模式表单,用于在MDI Windows表单应用程序中显示数据(示例代码中为Form1)。每个表单都有一个按钮,可以使用ShowDialog(示例代码中的Form2)以模态方式打开另一个表单,该按钮允许编辑Form1中显示的数据。这些模式表单有一个取消按钮,通过将DialogResult设置为Cancel关闭表单而不保存更改 我想实现一个计时器,在用户登录应用程序经过一定时间后关闭所有表单。如果计时器在模态窗体打开时触发,则会出现问题 public partial class

我有几个带有网格的无模式表单,用于在MDI Windows表单应用程序中显示数据(示例代码中为
Form1
)。每个表单都有一个按钮,可以使用
ShowDialog
(示例代码中的
Form2
)以模态方式打开另一个表单,该按钮允许编辑
Form1
中显示的数据。这些模式表单有一个取消按钮,通过将
DialogResult
设置为
Cancel
关闭表单而不保存更改

我想实现一个计时器,在用户登录应用程序经过一定时间后关闭所有表单。如果计时器在模态窗体打开时触发,则会出现问题

public partial class Form1 : 
{ //Constructor ommited for brevity
    private void btnEditData_Click(object sender, EventArgs e)
    {
        var form2 = new Form2();
        timer1.Tick += (_, __) =>
        {
            form2.DialogResult = DialogResult.Cancel;
            this.Close(); // this executes before form2.ShowDialog returns
        };
        timer1.Interval = 5_000;
        timer1.Enabled = true;
        form2.ShowDialog();
        reloadData(); // here Form1 is already disposed because Close 
        // has been called on it. An exception is thrown as a consequence
    }

    private void reloadData()
    {
        if (this.IsDisposed)
            // simulate using a disposed form
            throw new ObjectDisposedException(this.Name); 
    }
}
我的意图是在
form2.ShowDialog()
返回并且
btnEditData\u Click
方法完成后,以某种方式安排调用
Form1.Close()
,这样就不会有使用已处理表单的危险

编辑 看过代码后,我建议在Tick事件处理程序中引入第三个选项,用于决定是否必须关闭表单。例如,
中止

 timer1.Tick += (_, __) =>
    {
        form2.DialogResult = DialogResult.Abort;
    };
if (form2.ShowDialog() == DialogResult.Abort) Close();    
else reloadData();

第一个想法:保持简单和干净。您不必跟踪打开的表单,在MDI应用程序中,父表单的
MdiChildren
属性将为您提供所有表单。 然后,要处理结束部分,可以使用.Net中的现有功能

  • 一个困难的方法是使用。加载Windows DLL并使用它们的函数枚举所有窗体,然后关闭所需的窗体。您还可以模拟单击“取消”按钮。您必须从函数(识别表单)和表单的子项开始。我喜欢这个选项,因为您可以完全控制表单和控件,但如果不熟悉这个概念,可能会让您头疼
  • 您可以查看FormClosing事件并订阅它。此事件在窗体关闭之前激发,您可以使用它进行清理
  • 使用OOP-继承和重写。您可以创建一个带有自定义关闭函数的基本表单来进行清理(然后通过它继承所有表单),也可以覆盖表单的关闭函数来实现您的目标
    也许你可以发布一些代码,以帮助人们提供解决方案?根据@francesco-b建议发布一些代码