Как избежать нескольких экземпляров формы Windows в С#

StackOverflow https://stackoverflow.com/questions/1403600

  •  05-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

пример: 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);
    }
}

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

Вот мое решение в 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 закрытым, чтобы никто не смог случайно создать один из них. Затем вызовите рефлексию, преобразуйте ctor в public и убедитесь, что вы создали один и только один его экземпляр.

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

using System.Diagnostics;

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top