在C#中,如果CTOR / Load事件出现故障,关闭新打开的表单的最佳方法是什么?

时间:2021-01-12 16:00:08

What is the best method [pattern] to close a newly opened Windows form in C#/.NET if there is a trappable error in the CTOR/_Load event ?

如果CTOR / _Load事件中存在可捕获的错误,在C#/ .NET中关闭新打开的Windows窗体的最佳方法[模式]是什么?

i.e.,

bool loadError;
MyForm_Load(...) {
  try {
  } catch (SomeException ex) {
    // Alert the user
    MessageBox.Show("There was a critical error.  The form will close.  Please try again.");

    // There was some sort of error, and I just want the form to close now.
    loadError = true;

    return;
  }
}

Now I want to act on loadError. I've tired using the Activate event, but that yielded no results. Any suggestions on what the best way to go about doing this is ?

现在我想对loadError采取行动。我已经厌倦了使用Activate事件,但没有产生任何结果。关于做这件事的最佳方法的任何建议是什么?

Update: Perhaps I should have been a little more explicit. Doing a "this.Close();" during the forms Load event will cause an exception to be thrown as a form can't be closed and the exception will be "Cannot call Close() while doing CreateHandle()".

更新:也许我应该更明确一点。做一个“this.Close();”在表单期间,Load事件将导致抛出异常,因为表单无法关闭,异常将是“在执行CreateHandle()时无法调用Close()”。

3 个解决方案

#1


As I mentioned in the comments, I tried with a sample example and called this.Closed() inside of the catch block. It worked just fine. The application showed the message box and didn't show me the form. I am using .NET3.5 SP1, though.

正如我在评论中提到的,我尝试了一个示例示例,并在catch块中调用this.Closed()。它运作得很好。应用程序显示了消息框,但没有向我显示表单。不过,我正在使用.NET3.5 SP1。

Suppose this error happens in earlier version of .NET Framework, can you try to see whether any of the followings works for you or not? They, again, seem to work fine on my machine, yet, cannot guarantee whether they will work on yours, though.

假设在早期版本的.NET Framework中发生此错误,您是否可以尝试查看以下任何内容是否适合您?然而,它们似乎在我的机器上工作正常,但是,不能保证它们是否能在你的机器上工作。

  1. Put this.Close() in the finally block to see it works

    将this.Close()放在finally块中以查看它的工作原理

    finally { if (this.loadError) this.Close(); }

    finally {if(this.loadError)this.Close(); }

  2. Defer the Form.Close() after Form.OnLoad event handler completes.

    在Form.OnLoad事件处理程序完成后推迟Form.Close()。

See the sample below: this does not contain any anonymous delegate or lambda expression for older versions of .NET FW. Please forgive me for partial class :)

请参阅下面的示例:对于旧版本的.NET FW,它不包含任何匿名委托或lambda表达式。请原谅我的部分课程:)

using System;
using System.Windows.Forms;

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

        public delegate void InvokeDelegate();


        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                MyTroublesomeClass myClass = new MyTroublesomeClass();
            }
            catch (ApplicationException ex)
            {

                MessageBox.Show("There was a critical error.  The form will close.  Please try again.");

                this.BeginInvoke(new InvokeDelegate(CloseTheForm));
            }

        }
        private void CloseTheForm()
        {
            this.Close();
        }
    }

    class MyTroublesomeClass
    {
        public MyTroublesomeClass()
        {
            throw new ApplicationException();
        }
    }
}
  1. Use the combination of 1 and 2 if 2 does not work:

    如果2不起作用,请使用1和2的组合:

    finally { if (this.loadError) this.BeginInvoke(new InvokeDelegate(CloseTheForm)); }

    finally {if(this.loadError)this.BeginInvoke(new InvokeDelegate(CloseTheForm)); }

#2


Have you tried calling this.Close() in the FormShown event? That event is fired once when your form is first shown. You could check your error condition there and then call close.

您是否尝试在FormShown事件中调用this.Close()?当您的表单首次显示时,该事件将被触发一次。您可以在那里检查您的错误情况,然后致电关闭。

#3


I think you should call form.Dispose() and then set form = null. This should cover for the main usage scenario.

我认为你应该调用form.Dispose()然后设置form = null。这应该涵盖主要使用场景。

#1


As I mentioned in the comments, I tried with a sample example and called this.Closed() inside of the catch block. It worked just fine. The application showed the message box and didn't show me the form. I am using .NET3.5 SP1, though.

正如我在评论中提到的,我尝试了一个示例示例,并在catch块中调用this.Closed()。它运作得很好。应用程序显示了消息框,但没有向我显示表单。不过,我正在使用.NET3.5 SP1。

Suppose this error happens in earlier version of .NET Framework, can you try to see whether any of the followings works for you or not? They, again, seem to work fine on my machine, yet, cannot guarantee whether they will work on yours, though.

假设在早期版本的.NET Framework中发生此错误,您是否可以尝试查看以下任何内容是否适合您?然而,它们似乎在我的机器上工作正常,但是,不能保证它们是否能在你的机器上工作。

  1. Put this.Close() in the finally block to see it works

    将this.Close()放在finally块中以查看它的工作原理

    finally { if (this.loadError) this.Close(); }

    finally {if(this.loadError)this.Close(); }

  2. Defer the Form.Close() after Form.OnLoad event handler completes.

    在Form.OnLoad事件处理程序完成后推迟Form.Close()。

See the sample below: this does not contain any anonymous delegate or lambda expression for older versions of .NET FW. Please forgive me for partial class :)

请参阅下面的示例:对于旧版本的.NET FW,它不包含任何匿名委托或lambda表达式。请原谅我的部分课程:)

using System;
using System.Windows.Forms;

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

        public delegate void InvokeDelegate();


        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                MyTroublesomeClass myClass = new MyTroublesomeClass();
            }
            catch (ApplicationException ex)
            {

                MessageBox.Show("There was a critical error.  The form will close.  Please try again.");

                this.BeginInvoke(new InvokeDelegate(CloseTheForm));
            }

        }
        private void CloseTheForm()
        {
            this.Close();
        }
    }

    class MyTroublesomeClass
    {
        public MyTroublesomeClass()
        {
            throw new ApplicationException();
        }
    }
}
  1. Use the combination of 1 and 2 if 2 does not work:

    如果2不起作用,请使用1和2的组合:

    finally { if (this.loadError) this.BeginInvoke(new InvokeDelegate(CloseTheForm)); }

    finally {if(this.loadError)this.BeginInvoke(new InvokeDelegate(CloseTheForm)); }

#2


Have you tried calling this.Close() in the FormShown event? That event is fired once when your form is first shown. You could check your error condition there and then call close.

您是否尝试在FormShown事件中调用this.Close()?当您的表单首次显示时,该事件将被触发一次。您可以在那里检查您的错误情况,然后致电关闭。

#3


I think you should call form.Dispose() and then set form = null. This should cover for the main usage scenario.

我认为你应该调用form.Dispose()然后设置form = null。这应该涵盖主要使用场景。