第二次调用 Form.Show() 时出错

Error when calling Form.Show() a second time

提问人:Saeed Kiarsi Zadeh 提问时间:11/27/2018 最后编辑:Jason GeigerSaeed Kiarsi Zadeh 更新时间:11/27/2018 访问量:1328

问:

我有一个带按钮的主窗体。

OnClick 该按钮执行以下操作...

Form AllBook = new Form();
//Does some other processing and SQLReader querying.
AllBook.Show();

之后,我关闭了表单。当我尝试再次显示它时,我收到此错误。

System.ObjectDisposedException:“无法访问已释放的对象。 对象名称:'Form'。

// objects
Form AllBook        = new Form();
ComboBox booksList  = new ComboBox();
ComboBox chapters   = new ComboBox();
Panel topPannel     = new Panel();
Panel txtPannel     = new Panel();
TextBox mainText    = new TextBox();

private void button1_Click(object sender, EventArgs e)
{
    // add objects to form
    AllBook.Controls.Add(topPannel);
    topPannel.Controls.Add(booksList);

    // get combobox items from another Method
    int chapterCount = countChapters(43);
        for (int i = 1; i <= chapterCount; i++) {
            chapters.Items.Add(i);
        }

    topPannel.Controls.Add(chapters);
    AllBook.Controls.Add(txtPannel);

    txtPannel.Controls.Add(mainText);

    AllBook.Show();
}

// count books chapters
public int countChapters(int bookNum) {
     int chapter = 0;
     switch (bookNum) {
         case 1:
            chapter = 50;
              break;
              case 2:
            chapter = 40;
              break;
              case 3:
            chapter = 27;
              break;
              case 4:
            chapter = 36;
              break;
        .....
}
C# WinForms ShowDialog

评论

2赞 Dour High Arch 11/27/2018
您需要向我们展示如何“关闭表格并再次打开AllBook表格”。
3赞 H.G. Sandhagen 11/27/2018
如果关闭窗体,则会释放该窗体。要再次使用它,您必须创建一个新的或使用 代替 .AllBooks.CloseHideClose
0赞 LarsTech 11/27/2018
每次单击按钮时都调用此名称。AllBook = new Form();
0赞 Caius Jard 11/27/2018
为什么要以编程方式生成表单?只需使用 Windows 窗体设计器,这样它看起来就不会一团糟,然后在每次要显示窗体时创建一个新实例
0赞 Saeed Kiarsi Zadeh 11/29/2018
因为我想要一个用于低内存容量计算机的程序

答:

0赞 Jason Geiger 11/27/2018 #1

@H.G. Sandhagen 和 @LarsTech 是正确的。

关闭应处理表格。如果你想再次展示它,你需要......

Form AllBook = new Form();
AllBook.Show();

...每次。

编辑:添加进一步说明。 以某种方式关闭表单也会调用 Disopose()。

源:

关闭窗体后,在对象中创建的所有资源均为 关闭并处理表单。您可以阻止关闭表单 在运行时通过处理 Closing 事件并设置 Cancel 作为参数传递给事件的 CancelEventArgs 的属性 处理器。如果您要关闭的表单是您的启动表单 application,您的应用程序结束。

https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.form.close?view=netframework-4.7.2

评论

0赞 Saeed Kiarsi Zadeh 11/27/2018
我想这样做,但是 - AllBook_closeForm() - 不适合我。所以我不能在关闭它时处理表格。
0赞 Jason Geiger 11/27/2018
@user2215032 我补充了澄清。AllBook.Close() 会自动调用 AllBook.Dispose()。如果需要,您可以禁用它。说明在我回答的链接中。
0赞 pm100 11/27/2018
只需执行 AllBooks.Hide 而不是关闭
0赞 Jason Geiger 11/27/2018
@pm100,您仍然需要在窗体上创建一个关闭事件并设置 Cancel 属性。Microsoft文章的链接很好地详细介绍了它。
0赞 Joe White 11/27/2018 #2

默认情况下,关闭表单将释放它。但是,您可以通过重写 Closing 事件来更改此行为。

因此,您应该:

  • 每次显示表单时,都会创建一个新的表单实例,并允许 WinForms 在用户关闭表单时释放它;或
  • 重写 Closing 事件,以便关闭会导致窗体被隐藏而不是被释放,此时您将能够多次显示相同的窗体:

    private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
    {
        Hide();
        e.Cancel = true;
    }
    

请注意,如果您选择第二个选项,则在完成表单后由您决定是否调用该表单。Dispose()

0赞 preciousbetine 11/27/2018 #3

当表单关闭时,它会自动被处理掉,因此您可以在再次显示它之前使用以下命令刷新它:

   Allbook.Refresh();