如何在c#中避免多个windows窗体实例

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在c#中避免多个windows窗体实例相关的知识,希望对你有一定的参考价值。

如何在c#中避免多个windows窗体实例?我只想运行一个表单实例。因为有可能从我的应用程序的许多页面打开相同的表单。

答案

实施Singleton pattern

一个例子:CodeProject: Simple Singleton Forms(好吧,它在VB.NET中,但只是为了给你一个线索)

另一答案

单身人士不是面向对象的。它们只是全局变量的对象版本。你可以做的是使Form类的构造函数为private,所以没有人可以意外地创建其中的一个。然后调用反射,将ctor转换为public,并确保创建一个且只有一个实例。

另一答案

您可以在打开表单之前检查现有流程:

using System.Diagnostics;

bool ApplicationAlreadyStarted()
{
  return Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length == 0;
}

我不知道GetProcessesByName方法是否受UAC或其他安全措施的影响。

另一答案

是的,它有单身模式,

用于创建单个对象的代码,

public partial class Form2 : Form
{
 .....
 private static Form2 inst;
 public static Form2  GetForm
 {
   get
    {
     if (inst == null || inst.IsDisposed)
         inst = new Form2();
     return inst;
     }
 }
 ....
}

调用/显示此表单,

Form2.GetForm.Show();
另一答案

当您显示对话框时,只需使用.ShowDialog();而不是.Show();

另一答案

我应用于我的项目以便将此表单再次放在前台的一个解决方案是:

    private bool checkWindowOpen(string windowName)
    {
        for (int i = 0; i < Application.OpenForms.Count; i++)
        {
            if (Application.OpenForms[i].Name.Equals(windowName))
            {
                Application.OpenForms[i].BringToFront();
                return false;
            }
        }
        return true;
    }

windowName本质上是Windows窗体的类名,返回值可用于不创建新的窗体实例。

另一答案

如果您的系统可以为不同的实例数据显示相同类型的表单,那么您可以创建一个检查系统,该系统迭代所有现有的打开表单,查找唯一的实例数据标识符,然后重新显示任何找到的表单。

例如有一个表单类'CustomerDetails',它包含一个公共属性'CustomerUniqueID':

foreach(Form f in CurrentlyDisplayedForms)
{
    CustomerDetails details = f as CustomerDetails;
    if((details != null) && (details.CustomerUniqueUD == myCustomerID))
    {
        details.BringToFront();
    }
    else
    {
        CustomerDetails newDetail = new CustomerDetails(myCustomerID);
    }
}

我们还使用相同的机制自动强制刷新数据绑定,其中客户的数据已被编辑和保存。

另一答案

这是我在ShowForm()中的解决方案:

    private void ShowForm(Type typeofForm, string sCaption)
    {
        Form fOpen = GetOpenForm(typeofForm);
        Form fNew = fOpen;
        if (fNew == null)
            fNew = (Form)CreateNewInstanceOfType(typeofForm);
        else
            if (fNew.IsDisposed)
                fNew = (Form)CreateNewInstanceOfType(typeofForm);

        if (fOpen == null)
        {
            fNew.Text = sCaption;
            fNew.ControlBox = true;
            fNew.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            fNew.MaximizeBox = false;
            fNew.MinimizeBox = false;
            // for MdiParent
            //if (f1.MdiParent == null)
            //    f1.MdiParent = CProject.mFMain;
            fNew.StartPosition = FormStartPosition.Manual;
            fNew.Left = 0;
            fNew.Top = 0;
            ShowMsg("Ready");
        }
        fNew.Show();
        fNew.Focus();
    }
    private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
    {
        ShowForm(typeof(FAboutBox), "About");
    }

    private Form GetOpenForm(Type typeofForm)
    {
        FormCollection fc = Application.OpenForms;
        foreach (Form f1 in fc)
            if (f1.GetType() == typeofForm)
                return f1;

        return null;
    }
    private object CreateNewInstanceOfType(Type typeofAny)
    {
        return Activator.CreateInstance(typeofAny);
    }

    public void ShowMsg(string sMsg)
    {
        lblStatus.Text = sMsg;
        if (lblStatus.ForeColor != SystemColors.ControlText)
            lblStatus.ForeColor = SystemColors.ControlText;
    }
另一答案

检查这个link

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
          {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}
另一答案

试试这个代码

Public class MyClass
{
    //Create a variable named 
    public static int count = 0;
    //Then increment count variable in constructor
    MyClass()
    {
        count++;
    }
}

在为上述类'MyClass'创建对象时,请检查计数值是否大于1

class AnotherClass
{
    public void Event()
    {
        if(ClassName.Count <= 1)
        {
            ClassName classname=new ClassName();
        }
    }
}
另一答案

这是一个简单的方法。

检查表单是否为空或已被处置。如果这是真的,我们创建一个新的表单实例。

否则我们只显示已经运行的表单。

    Form form;
    private void btnDesktop_Click(object sender, EventArgs e)
    {
        if (form == null || desktop.IsDisposed)
        {
            form = new Form();
            form.Show();
        }
        else
        {
            form.WindowState = FormWindowState.Normal;
        }
    }

以上是关于如何在c#中避免多个windows窗体实例的主要内容,如果未能解决你的问题,请参考以下文章

C#窗体设计——多个窗体之间的调用

标签文本在 C++/CLR Windows 窗体上未更改

如何避免在 C# 中完成线程?

C#如何在 Windows 窗体应用程序中使用事件

wpf 一个窗体中点击空白部分关闭另一个窗体

如何通过USB连接多个红外摄像机和C#