1

I'm working on a project, and have two forms - One is the main form, the other a console-akin form made up of a split panel and a listbox (in panel 1)

I call a method ( writeToConsole(string textToWrite) ) which - as the name suggests - adds a line of text to the list box in the consoleWindow form

The issue I'm having is that, to show this form, I use a button that calls the show command. However, if I close said form with the "x" button in the top right corner, and then click the Show Console Button again, I get this:

ObjectDisposedException

 "Cannot access a disposed object.
Object name: 'consoleOutput'."

Now, I sort of understand the issue - I had it a month or two ago, and from what I understand its because when you press the x it closes the form, meaning it has to be reinitialized / reloaded before it can be show - hence the error is ( in a very basic nutshell) "I can't show you something that doesn't exist / is in limbo"

(Again, thats the whole "Sort of on the face of it thats what it means, but really no its deeper than that" view - I understand its deeper than just that)

My question is this: Can someone please explain to me what exactly is going on / wrong, and the best way to do this sort of thing?

I understand the concept of the error, and I know a way or two to fix it, but I'm wanting to be a programmer, hence would like to know (at the very least) the flow of events for this situation and expand on my knowledge

Thanks

Just to be safe:

consoleOutput consoleOutput = new consoleOutput();

        private void btnShowConsole_Click(object sender, EventArgs e)
        {
            //Check to see if the console is visible, of which if its not, make it so
            //If it is on the other hand, just bring it to the front to show the user
            if (consoleOutput.Visible == false)
                consoleOutput.Show();
            else
                consoleOutput.BringToFront();
        }
Gareth Jones
  • 1,241
  • 4
  • 17
  • 38
  • 1
    http://stackoverflow.com/a/2021708/251311 – zerkms Aug 13 '13 at 01:42
  • You need to show the code you use to close the form, and to show it again. But it sounds like you need a new.... – jmoreno Aug 13 '13 at 02:53
  • @jmoreno I've added the code, but I didn't think it was needed because its very basic - just the show command, as I said in the question. As pointed out in Wayne's answer, by creating a new form each time would mean loss of data – Gareth Jones Aug 13 '13 at 03:13

2 Answers2

3

Native operating system resources are a valuable commodity. In order to use them efficiently, programs should not hold onto those resources for longer than is necessary. In managed code, the .NET framework provides the System.IDisposable interface. Implementations of this interface can be instructed, via the Dispose() method, to release or dispose any resources that that implementation was responsible for creating (managed or unmanaged) in a timely fashion.

In the case of a WinForms application, almost all visual components involve native operating system resources to some degree, and so those components implement IDisposable. When Dispose()d, or Close()d, they will release their native resources (although the component itself is still accessible to the program via its reference).

One of the requirements of the IDisposable contract is that implementations should not allow access to the object via a public member if it's already been disposed. If such access is attempted, ObjectDisposedException should be thrown.

In your specific case, you have a couple of options:

1) arrange it so that the Form doesn't actually close, but instead gets hidden, and can be made visible again if the main form needs to show it again (note that if the form is doing any kind of work, hiding it won't necessarily stop that work, and that may or may not be desired in your case).

2) create a new instance of the Form every time you want to show it (but anything being displayed on a previous incarnation of the Form will be lost when it's closed).

lesscode
  • 6,221
  • 30
  • 58
2

You probably want something like this:

private void ConsoleOutput_FormClosing(object sender, FormClosingEventArgs e)
{
   this.Hide();
   e.Cancel = true; // cancel the close event.
}

You'll need to subscribe to the event ... don't forget to unsubscribe when you want to allow the form to close.

jmoreno
  • 12,752
  • 4
  • 60
  • 91