简体   繁体   English

如何从另一个表单关闭和重新打开一个表单?

[英]How to close and reopen a form from another form?

I have a list box with a list of employees and when the event of selected index changed is called a new form opens with some employee info such as email, name, location.我有一个包含员工列表的列表框,当调用selected index changed的事件时,会打开一个新表单,其中包含一些员工信息,例如 email、姓名、位置。 But when another user is clicked I want the previous form to close and open the new selected employee.但是,当单击另一个用户时,我希望以前的表单关闭并打开新选择的员工。

This is the current code I am using to try and close the form and then reopen it, but I am getting an error with the dispose call:这是我用来尝试关闭表单然后重新打开它的当前代码,但是我在 dispose 调用中遇到错误:

System.ObjectDisposedException: 
"Cannot access a disposed object. Object name: 'EmployeeInfoPopup'.

The code is inside of the event EmployeeListBox_SelectedIndexChanged .代码位于事件EmployeeListBox_SelectedIndexChanged内。

EmployeeInfoPopup popup = new EmployeeInfoPopup();
if(popup.Enabled == true)
{
     popup.Dispose();
     popup.employeePopupLayout(employeeListBox.SelectedIndex);
     popup.Show();
}
else
{
     popup.employeePopupLayout(employeeListBox.SelectedIndex);
     popup.Show();
}

This is the method that is called in the EmployeeInfoPopup Form这是在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]}");
}

You can try this pattern:你可以试试这个模式:

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);
}

We use a dictionary of opened EmployeeInfoPopup keyed by the listbox item index.我们使用由列表框项索引键控的打开的 EmployeeInfoPopup 字典。

This let you have multiple forms opened same time if you change the Close by a Show .如果您更改Close by a Show ,这可以让您同时打开多个 forms 。

Then we check if the form is already created to close (or show) it or to create, initialize and open it.然后我们检查表单是否已经创建以关闭(或显示)它或创建、初始化和打开它。

On the FormClosed event of the EmployeeInfoPopup , add:EmployeeInfoPopupFormClosed事件中,添加:

TheFormWithTheListBoxClassName.EmployeeInfoPopupClosed(this);

This works fine if you have only one instance of TheFormWithTheListBoxClassName, else more code is needed to manage the instances using a dictionary of the previous dictianary keyed by TheFormWithTheListBoxClassName.如果您只有一个 TheFormWithTheListBoxClassName 实例,则此方法可以正常工作,否则需要更多代码来使用由 TheFormWithTheListBoxClassName 键入的上一个字典的字典来管理实例。

Let me know your case and I'll update the code.让我知道你的情况,我会更新代码。

If instance is Dispose d如果实例是Dispose d

 popup.Dispose();

you can't opened it any more (all required resources like Handle are released )你不能再打开它(所有必需的资源,如Handle释放

 popup.Show(); // <- Will throw exception

You can try to find out if there's opened EmployeeInfoPopup form (and Close it):您可以尝试查看是否打开EmployeeInfoPopup表单(并Close它):

  using System.Linq;

  ... 

  // Close the last opened EmployeeInfoPopup if it exists
  Application
    .OpenForms
    .OfType<EmployeeInfoPopup>()
    .LastOrDefault()
   ?.Close();

If you want to delete all such forms:如果要删除所有此类 forms:

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

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

And then create and open a new EmployeeInfoPopup istance然后创建并打开一个新的EmployeeInfoPopup istance

  // Create a new EmployeeInfoPopup instance
  EmployeeInfoPopup popup = new EmployeeInfoPopup(); 

  popup.employeePopupLayout(employeeListBox.SelectedIndex);
  popup.Show();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM