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

有帮助吗?

解决方案

实施单身人士模式

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

其他提示

是的,它有单例模式,

创建单例对象的代码

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窗体的类名 返回值可用于不创建新的表单实例。

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

e.g。具有表单类'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;
    }

查看此链接

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

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

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

using System.Diagnostics;

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

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top