Pergunta

Como evitar várias instâncias do formulário do Windows em c # ?? eu quero apenas uma instância do formulário em execução. Porque há chances de abrir o mesmo formulário a partir de muitas páginas do meu aplicativo.

Foi útil?

Solução

Singleton

Um exemplo: CodeProject: Formas Singleton simples (ok, é em VB NET, mas apenas para lhe dar uma pista)

Outras dicas

Sim, tem padrão Singleton,

Código para criar um objeto singleton,

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

Invoke / Mostrar esta forma,

Form2.GetForm.Show();

Quando você exibir o diálogo simplesmente usar .ShowDialog(); vez de .Show();

Uma solução apliquei ao meu projeto, a fim de trazer este formulário novamente em primeiro plano é:

    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 é essencialmente o nome da classe do seu Windows Form e valor de retorno pode ser usado para não criar uma nova instância do formulário.

Se o seu sistema tem a possibilidade de mostrar o mesmo tipo de formulário para diferentes dados de instância, em seguida, você pode criar um sistema de verificação que repete todos os formulários abertos existentes, procurando uma base de dados instância exclusivos identificador e, em seguida, re-exibir qualquer forma encontrada.

por exemplo. tendo uma classe de formulário 'CustomerDetails' que contém uma propriedade pública '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);
    }
}

Nós também usamos o mesmo mecanismo para forçar automaticamente atualizações de ligação de dados onde os dados de um cliente foi editado e salvo.

Aqui está a minha solução em 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;
    }

ligação :

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

Tente este código

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

Ao criar o objeto para a classe acima 'MyClass' verificar o valor de contagem superior a 1

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

Aqui está uma maneira simples de fazê-lo.

Verifique se o formulário for nulo, ou foi descartado. Se isso for verdade, criamos uma nova instância do formulário.

Caso contrário, apenas mostrar a forma já em execução.

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

Singletons não é orientada a objetos. Eles são simplesmente a versão de objeto de variáveis ??globais. O que você pode fazer é fazer com que o construtor da classe Form privada, para que ninguém possa acidentalmente criar um destes. Em seguida, chamar na reflexão, converter o ctor ao público e certifique-se de criar um e somente um exemplo disso.

Você pode verificar os processos existentes antes de abrir o formulário:

using System.Diagnostics;

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

Eu não sei se o método GetProcessesByName é afetada pela UAC ou outras medidas de segurança.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top