如何防止我的程序打开同一个窗口表格两次

时间:2014-01-12 20:45:39

标签: c# .net winforms visual-studio-2010

我正在开发一个项目,我正在创建一个实例并在我的程序中打开一个特定的表单,就像我使用下面的代码打开一个表单:

  frm2 cs = new frm2();
  cs.Show();

但这里的问题是每次我点击按钮它只是打开一个新窗口而前一个也打开了,我想在这里做的就是当我点击按钮并且那个窗口已经打开然后它只是去打开已经打开的窗户,除了打开新窗户。 希望你们理解我的问题,并帮助我做到这一点。

编辑:

我试过这段代码:我在frm2.cs文件中写的代码是:

   public partial class frm2 : Form
    {

       private static frm2 _form2 = null; 

        public frm2()
        {
            InitializeComponent();
        }

        public static frm2 Instance
        {
            get
            {
                if (_form2 == null)
                {
                    _form2 = new frm2();
                }
                return _form2;              
            }
        }

并在frmMain.cs文件中,我编码访问实例并打开项目:

private void addProductToolStripMenuItem_Click(object sender, EventArgs e)
  {
       frm2.Instance.Show();  

       //frm2 cs = new frm2();
      //cs.Show();
  }

第一次运行正常,但是当我打开frm2时,关闭它然后再次尝试打开它,编译器在frm2.Instance.Show();给出错误,错误来了

: Cannot access a disposed object.
Object name: 'frm2'.

7 个答案:

答案 0 :(得分:7)

保存在全局类变量中打开的表单实例,然后,如果此变量不为null,则只调用Show而不是打开againg。但是应该遵循一些提示

public class Form1: Form
{
     private frm2 _currentInstance = null;
     ....

     if(_currentInstance != null)
     {
         _currentInstance = new frm2();
         _currentInstance.FormClosed += instanceHasBeenClosed;
     }
     _currentInstance.Show();

     ....

     private void instanceHasBeenClosed(object sender, FormClosedEventArgs e)
     {
         _currentInstance = null;
     }
}

为_currentInstance订阅FormClosed事件非常重要。这样,当用户关闭实例时,将通知您的Form1。并且您可以将内部变量重置为null,因此在随后的单击中您可以再次重新打开实例

还可以使用Application.OpenForms集合来检查您的表单是否显示

frm2 f = Application.OpenForms["NameOfForm2"];
if(f != null)
   f.BringToFront();
else
{
   frm2 f = new frm2();
   f.Show();
}

答案 1 :(得分:3)

您可以使用singleton设计模式始终返回相同的实例

public partial class Form2 : Form
{
    private  static Form2  _form2 = null; 
    private Form2()
    {
        InitializeComponent();
    }
    public static  Form2 Instance
    {
        get
        {
            if (_form2 == null)
            {
                _form2 = new Form2();  
            }
            return _form2;  

        }
    }


}

//使用它来调用实例

 Form2.Instance.Show();  

答案 2 :(得分:3)

我知道你不想写那么多代码,但似乎这是唯一的方法。

至少,您可以通过编写通用代码将该代码与表单分开。

var f = FormManager.Show<Form2>(); //create a new form.
f = FormManager.Show<Form2>(); //show the existing form.
f.Close();
f = FormManager.Show<Form2>(); //create a new form

public static class FormManager
{
    static Dictionary<Type, Form> _Forms = new Dictionary<Type, Form>();

    public static T Show<T>() where T: Form, new()
    {
        var type = typeof(T);
        Form f = null;
        if(_Forms.TryGetValue(type,out f))
        {
            f.BringToFront();
        }
        else
        {
            f = new T();
            f.FormClosing += (s, e) => _Forms.Remove(s.GetType());
            _Forms.Add(type, f);
            f.Show();
        }
        return (T)f;
    }
}

答案 3 :(得分:2)

单例模式可能是一种方法 - 只需将其应用于Windows表单(您可以在C#中查看此链接以获取单例模式的描述:http://msdn.microsoft.com/en-us/library/ff650316.aspx)。

答案 4 :(得分:0)

检查该表格中的多个按钮是否已打开:

private bool isOpen(string name)
        {
            IsOpen = false;
            foreach (Form f in Application.OpenForms)
            {
                if (f.Text == name)
                {
                    IsOpen = true;
                    f.Focus();
                    break;
                }
            }

            if (IsOpen == false)
            {
                return IsOpen;
            }
            return IsOpen;
        }

在按钮单击中调用此选项以检查当前表单:

 if (isOpen("Item Import Master")) ;
            else
            {
                Item_Import_Master obj1 = new Item_Import_Master();
                obj1.Show();
            }

答案 5 :(得分:0)

在再次显示表单之前,您需要检查是否已处置该表单,否则您将无法访问已处置的对象实例

类似的东西应该起作用

private static AdvancedRDSWindow form2;
private AdvancedRDSWindow()
{
    InitializeComponent();
}
public static AdvancedRDSWindow Instance
{
    get
    {
        if (form2 == null || form2.IsDisposed)
        {
            form2 = new AdvancedRDSWindow();
        }
        return form2;

然后您可以使用一个按钮来显示它

private void AdvancedRDS_Click(object sender, EventArgs e)
{
    AdvancedRDSWindow.Instance.Show(); 
}

答案 6 :(得分:0)

在按钮点击事件中使用此代码

如果已打开该表单,它将把该表单置于最前面

# Here is my code.. #

foreach (Form form in Application.OpenForms)
{
    if (form.GetType() == typeof(frm2))
    {
        form.Activate();
        return;
    }
}

frm2 frm = new frm2();
frm.Show();