Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/257.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# 关闭后处理表单_C#_Winforms_Forms_Dispose - Fatal编程技术网

C# 关闭后处理表单

C# 关闭后处理表单,c#,winforms,forms,dispose,C#,Winforms,Forms,Dispose,我在C#中遇到了一个新问题,即开合形式 我的问题是如何处理关闭后的表单 这是我的密码: Program.cs: static class Program { public static Timer timer; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefaul

我在C#中遇到了一个新问题,即开合形式

我的问题是如何处理关闭后的表单

这是我的密码:

Program.cs:

static class Program
{
    public static Timer timer;

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        timer = new Timer { Interval = 1000};
        timer.Start();

        Application.Run(new Form1());
    }
}
表格1.cs:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Form2 form = new Form2();
        form.ShowDialog();
       /// I've tried Dispose() method . but didn't work
    }
}
表格2.cs:

public partial class Form2 : Form
{
    public Form2()
    {
        InitializeComponent();
    }

    private void Form2_Load(object sender, EventArgs e)
    {
        Program.timer.Tick += timer_Tick;    
        Close();
        // I've tried Dispose() method instead of Close() but didn't work
    }

    private int count = 0; 
    void timer_Tick(object sender, EventArgs e)
    {
        count++;
        if (count == 5) MessageBox.Show("");
    }
}
编辑:
我的问题是:为什么当form2关闭时,消息框在5秒后显示

编辑:这个问题原来是关于处置的

首先,Dispose与垃圾收集无关。发生以下情况:

  • 您有一个全局计时器实例
  • 您可以创建form2
  • Form2订阅了计时器
  • 表格2已关闭和/或处置
  • 计时器事件激发、递增计数器并显示MessageBox
  • 计时器事件持续触发,直到应用程序关闭 需要理解的要点是,Close/Dispose只会更改表单的状态,而不会(不能)“删除”实例。所以(闭合的)表单在那里,计数器字段仍然在那里,事件触发


    好的,第一部分:

    使用(){}
    块会更好,但这应该可以:

        private void button1_Click(object sender, EventArgs e)
        {
            Form2 form = new Form2();
            form.ShowDialog();
           /// I've tried Dispose() method . but didn't work
            form.Dispose(); // should work
        }
    
    如果没有,请描述“不起作用”


    这很奇怪,但我假设这是问题的人工代码

    您的全局程序.Timer现在存储对Form2实例的引用,并将阻止收集该引用。它不会阻止它被释放/关闭,因此您的计时器将持续触发一个关闭的窗体,这通常会失败并导致其他问题

  • 不要这样做(给Form2它自己的计时器)
  • 使用FormClosed事件取消订阅:
    Program.timer.Tick-=timer\u Tick

  • 在使用后处理
    表单
    的最简单、最可靠的方法是将用法放在using块中

    using (Form2 form = new Form2()) {
      form.ShowDialog();
    }
    
    C#中的using块是一个基本上将上述内容扩展为以下代码的构造

    Form2 form;
    try {
      form = new Form2(); 
      ...
    } finally {
      if ( form != null ) {
        form.Dispose();
      }
    }
    
    ShowDialog()将窗体显示为模式对话框。这意味着在表单关闭之前,呼叫不会返回。
    请注意,在模式对话框上单击“关闭X”并不会关闭窗体,它只是将其隐藏。我猜这就是让你困惑的地方。 如果希望form1中的代码继续执行而不是阻塞,则应调用Show()而不是ShowDialog()。单击X时,非模态将关闭

    如果您确实需要一个阻塞模式对话框,则应使用其他答案中所述的using块围绕表单。
    构建模式对话框时,通常会添加“OK”按钮或类似按钮,并将表单的AcceptButton属性设置为该按钮,以允许用户通过按enter键关闭表单。同样,您可以添加“取消”按钮并设置CancelButton属性以捕获Esc键。

    在两个按钮上添加一个单击处理程序,相应地设置窗体的DialogResult属性并调用Close()。

    也许我读错了问题,但我认为先生们需要知道,要关闭作为form2.ShowDialog()打开的窗体(比如form2),需要在form2中设置form2.DialogResult。关闭表单并返回结果只需设置该成员。

    这是一个老问题,但它涉及到一些关于对象如何工作的有趣问题。形式本质上是一个对象。同一类的所有对象共享相同的方法,但每个对象都有自己的数据。这是什么意思?这意味着,关闭或处理对象不会从内存中释放/删除/删除任何代码。只有数据。所有这些都是关于对象的,不管是什么语言

    现在,特别是关于您的代码。让我们检查一行
    Program.timer.Tick+=timer\u Tick可以。这将在Form对象中向timer对象提供一个指向函数的指针。因此,现在,无论您对表单对象做什么,计时器对象都将继续调用该函数。计时器对象不关心窗体,甚至不知道窗体对象的存在。它只关心您将指针传递到的函数。就计时器对象而言,此函数是一个独立函数

    Form.Close()做什么?Close()处理表单使用的资源,也就是标记表单控件进行垃圾回收,除非使用ShowDialog显示表单。在这种情况下,必须手动调用Dispose()


    不用说,如果关闭/处理表单清除了内存中的函数,计时器对象将具有无效指针,程序将在5秒后崩溃。

    为什么要在垃圾收集器为您执行此操作之前处理表单(假设没有对剩余表单的引用)?“它不起作用”是什么意思意思是?是否引发异常?窗口是否消失?@Lazarus:问得好。+1对于建议使用语句,可能想给他举个例子。亲爱的Henk Holterman,删除计时器滴答事件是一个好的解决方案,但我的问题是,为什么消息框会显示窗体已处理的时间?@Mironline:为什么不应该?Ti也不应该mer或MessageBox都不需要该表单。尝试在timer_Tick中设置控件属性,将出现异常。在秒块中,form2必须在访问之前初始化。如果初始化,则它永远不等于null。我尝试过,但消息框在5秒后显示。
    Form2 form;
    try {
      form = new Form2(); 
      ...
    } finally {
      if ( form != null ) {
        form.Dispose();
      }
    }