Search code examples
c#winformsobjectdisposedexception

ObjectDisposedException while Showing a Form


I keep getting an ObjectDisposedExpection when I need to get a Form to show. Do you guys maybe know how to do this? In the foreach by NotitiesForm.Show() I get the error ObjectDisposedExpection. I am programming in Visual Studio Ultimate 2012 C#.

RichTextBox NotitiesTB = new RichTextBox();
private Form NotitiesForm;

/// <summary>
/// 
/// </summary>
/// <param name="label"></param>
/// 
public void NotitiesLatenZien()
{
    if (filename != null)
    {                
        BRTSignal signal = new BRTSignal(filename);
        BRTEventRepository Notities = new BRTEventRepository(signal);

        List<IBRTNote> note = Notities.ReadNotes();

        BRTEventService TijdNotities = new BRTEventService(signal);
        TijdNotities.MakeNoteTimesRelativeToTrack(note, 1);

        //TextBox NotitiesTB = new TextBox();
        //NotitiesTB.Name = "Notities";

        if (NotitiesForm == null)
        {
            NotitiesForm = new Form();
        }              

        NotitiesForm.Height = 600;
        NotitiesForm.Width = 1000;
        NotitiesForm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
        NotitiesForm.MaximizeBox = false;
        NotitiesForm.Disposed +=NotitiesForm_Disposed;

        NotitiesForm.Text = "Notities";

        NotitiesTB.Multiline = true;
        NotitiesTB.Height = 600;
        NotitiesTB.Width = 980;
        NotitiesTB.ReadOnly = true;

        NotitiesTB.Clear();

        //NotitiesTB.Click += NotitiesTB_Click;

        //NotitiesTB.SelectionStart = Convert.ToInt32(referenceLineSelectedPage);

        NotitiesTB.ScrollBars = System.Windows.Forms.RichTextBoxScrollBars.Both;

        NotitiesTB.Name = "Notities";

        NotitiesForm.Controls.Add(NotitiesTB);

        foreach (IBRTNote notes in Notities.ReadNotes())
        {
            //string test = Convert.ToString((notes.Time));
            //textBox1.Text = String.Concat(textBox1.Text, string.Concat(Environment.NewLine, notes.Text));
            if (NotitiesTB.Text == "")
            {
                NotitiesTB.Text += new BRTToDotNET.RTDateTime((long)notes.Time).ToDotNet().ToString() + "     " + notes.Text;
            }
            else
            {
                NotitiesTB.Text += "\r\n" + new BRTToDotNET.RTDateTime((long)notes.Time).ToDotNet().ToString() + "     " + notes.Text;
            }
            //MessageBox.Show("\r\n" + notes.Text);
            NotitiesForm.Show();
            NotitiesForm.BringToFront();
        }
    }
    else
    {
        MessageBox.Show("Er blijkt een .sig file te missen. Controleer of u een .sig file heeft ingeladen.");
    }
}

private void NotitiesForm_Disposed(object sender, EventArgs e)
{
    NotitiesForm = null;
} 

Solution

  • The code you posted seem "good enough". That is, you set the NotitiesForm variable when the object is disposed, and you create a new one if it's null. As long as all this code executes in the main UI thread, that part is fine.

    But note that all controls in a Form are disposed of when the Form is disposed. So your NotitiesTB control will be disposed of the first time your NotitiesForm is closed. You then add that control to the next Form instance you create, and when it's shown, you get the exception because you're trying to show a Form containing a control that has already been disposed.

    The right way to do this would be to design an actual Form subclass that already contains the RichTextBox instance you want. Then you don't have to keep adding a new instance to each new instance of the Form you create.

    Barring that, then you need to create a new RichTextBox instance to go with each new Form instance you create, e.g. in the same place where you have the NotitiesForm = new Form(); statement.