C# 如何从另一个窗体关闭和重新打开窗体?

C# 如何从另一个窗体关闭和重新打开窗体?,c#,winforms,events,callback,C#,Winforms,Events,Callback,我有一个包含员工列表的列表框,当调用选定索引更改事件时,会打开一个新表单,其中包含一些员工信息,如电子邮件、姓名、位置。但是,当单击其他用户时,我希望上一个表单关闭并打开新选定的员工 这是我用来尝试关闭表单然后重新打开表单的当前代码,但我在dispose调用中遇到错误: System.ObjectDisposedException: "Cannot access a disposed object. Object name: 'EmployeeInfoPopup'. 代码位于事件员工列表框\

我有一个包含员工列表的列表框,当调用
选定索引更改事件时,会打开一个新表单,其中包含一些员工信息,如电子邮件、姓名、位置。但是,当单击其他用户时,我希望上一个表单关闭并打开新选定的员工

这是我用来尝试关闭表单然后重新打开表单的当前代码,但我在dispose调用中遇到错误:

System.ObjectDisposedException: 
"Cannot access a disposed object. Object name: 'EmployeeInfoPopup'.
代码位于事件
员工列表框\u SelectedIndexChanged

EmployeeInfoPopup popup = new EmployeeInfoPopup();
if(popup.Enabled == true)
{
     popup.Dispose();
     popup.employeePopupLayout(employeeListBox.SelectedIndex);
     popup.Show();
}
else
{
     popup.employeePopupLayout(employeeListBox.SelectedIndex);
     popup.Show();
}
这是在
EmployeeInfoPopup
表单中调用的方法

public void employeePopupLayout(int currentEmployeeIndex)
{
     SeatingChart_2_0 seatingChart = new SeatingChart_2_0();
     employeeLabel.Text = ($"Name: {seatingChart.employeesNames[currentEmployeeIndex]}\nEmail: {seatingChart.employeesEmails[currentEmployeeIndex]}\nBuilding: {seatingChart.employeesBID[currentEmployeeIndex]}\nFloor: {seatingChart.employeesFID[currentEmployeeIndex]}\nSeat: {seatingChart.employeesSID[currentEmployeeIndex]}");
}

如果实例是
Dispose
d

 popup.Dispose();
您无法再打开它(所有必需的资源,如
Handle
都已释放)

如果要删除所有此类表单:

   var forms = Application
      .OpenForms
      .OfType<EmployeeInfoPopup>()
      .ToArray();

   foreach (var form in forms)
     form.Close();

您可以尝试以下模式:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows.Forms;

static private Dictionary<int, EmployeeInfoPopup> EmployeeInfoForms 
  = new Dictionary<int, EmployeeInfoPopup>();

private void EmployeeListBox_SelectedIndexChanged(object sender, EventArgs e)
{
  int index = EmployeeListBox.SelectedIndex;
  if ( EmployeeInfoForms.ContainsKey(index) )
  {
    EmployeeInfoForms[index].Close();
  }
  else
  {
    EmployeeInfoPopup popup = new EmployeeInfoPopup();
    EmployeeInfoForms.Add(index, popup);
    popup.employeePopupLayout(index);
    popup.Show();
  }
}

static internal void EmployeeInfoPopupClosed(EmployeeInfoPopup sender)
{
  var key = EmployeeInfoForms.FirstOrDefault(v => v.Value == sender).Key;
  if ( key != null )
    EmployeeInfoForms.Remove(key);
}
若您只有一个具有ListBoxClassName的FormW实例,则此方法可以正常工作,否则需要更多代码来使用由具有ListBoxClassName的FormW键入的上一个词典来管理实例


告诉我您的情况,我会更新代码。

我在dispose调用中遇到错误,请发布此错误,堆栈跟踪可能会有帮助吗?我最好的猜测是,如果代码被激活,你是<代码>处理<代码>弹出< /代码>实例,但是你试图访问<代码> SeaMePopuPoPult。“我要把它扔掉,扔掉,扔掉,不再使用它,我已经用完了,我保证再也不会使用它“。不要只是调用随机方法而不知道它们的作用。他们都会做事。在给他们打电话之前先弄清楚他们在做什么。那么有没有办法关闭弹出窗口,但不处理它?我需要在调用EmployeePopupPlayout之前调用popup.show()吗?@SauerweinB call
popup.Hide()
   var forms = Application
      .OpenForms
      .OfType<EmployeeInfoPopup>()
      .ToArray();

   foreach (var form in forms)
     form.Close();
  // Create a new EmployeeInfoPopup instance
  EmployeeInfoPopup popup = new EmployeeInfoPopup(); 

  popup.employeePopupLayout(employeeListBox.SelectedIndex);
  popup.Show();
using System;
using System.Linq;
using System.Collections.Generic;
using System.Windows.Forms;

static private Dictionary<int, EmployeeInfoPopup> EmployeeInfoForms 
  = new Dictionary<int, EmployeeInfoPopup>();

private void EmployeeListBox_SelectedIndexChanged(object sender, EventArgs e)
{
  int index = EmployeeListBox.SelectedIndex;
  if ( EmployeeInfoForms.ContainsKey(index) )
  {
    EmployeeInfoForms[index].Close();
  }
  else
  {
    EmployeeInfoPopup popup = new EmployeeInfoPopup();
    EmployeeInfoForms.Add(index, popup);
    popup.employeePopupLayout(index);
    popup.Show();
  }
}

static internal void EmployeeInfoPopupClosed(EmployeeInfoPopup sender)
{
  var key = EmployeeInfoForms.FirstOrDefault(v => v.Value == sender).Key;
  if ( key != null )
    EmployeeInfoForms.Remove(key);
}
TheFormWithTheListBoxClassName.EmployeeInfoPopupClosed(this);