tags:

views:

598

answers:

3

Hi everyone,

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 ?

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 ?

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()".

A: 

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

kek444
Unfortunately, that won't work either as you can't call Dispose while the window handle is being created.
Matthew M.
Yes, I see what you mean. What happens if you try to get the Form.Handle property? Referencing it should create it if it isn't created. Then maybe the window would be in a manageable state.
kek444
+2  A: 

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.

Chris Dunaway
+1  A: 

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.

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.

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

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

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

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 :)

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:

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

Chansik Im
BeginInvoke is indeed the answer it seems. Otherwise, still get the errors and latest .NET as well [3.5 SP1].
Matthew M.