Как избежать нескольких экземпляров windows form в c#

Как избежать нескольких экземпляров windows form в C# ?? мне нужен только один экземпляр запущенной формы. Потому что есть шансы открыть одну и ту же форму со многих страниц моего приложения.

11 ответов


реализовать Синглтон шаблон

пример: CodeProject: Простые Одноэлементные Формы (хорошо, это в 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 и возвращаемое значение можно использовать для того, чтобы не создавать новый экземпляр формы.


Если ваша система имеет возможность показывать один и тот же тип формы для разных данных экземпляра, вы можете создать систему проверки, которая повторяет все существующие открытые формы, ищет уникальный идентификатор данных экземпляра, а затем повторно отображает любую найденную форму.

например, наличие класса формы "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);
    }
}

мы также используем тот же механизм для автоматического принудительного обновления привязки данных, где a данные клиента были отредактированы и сохранены.


вот мое решение в 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" проверьте значение count больше 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;
        }
    }

Синглеты не являются объектно-ориентированными. Это просто объектная версия глобальных переменных. Что вы можете сделать, так это сделать конструктор класса формы частным, чтобы никто не мог случайно создать один из них. Затем вызовите отражение, преобразуйте ctor в public и убедитесь, что вы создали один и только один экземпляр.


вы можете проверить существующие процессы перед открытием формы:

using System.Diagnostics;

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

Я не знаю, влияет ли метод GetProcessesByName на UAC или другие меры безопасности.