문제

C#에서 여러 Windows 양식의 인스턴스를 피하는 방법 ?? 양식 실행의 하나의 인스턴스 만 원합니다. 내 응용 프로그램의 많은 페이지에서 동일한 양식을 열 가능성이 있기 때문입니다.

도움이 되었습니까?

해결책

구현 싱글 톤 패턴

an example: 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 양식의 클래스 이름이며 새 양식 인스턴스를 만들지 않기 위해 리턴 값을 사용할 수 있습니다.

시스템에 다른 인스턴스 데이터에 대해 동일한 유형의 양식을 표시 할 수있는 경우 기존의 모든 열기 양식을 반복하여 고유 인스턴스 데이터 식별자를 찾고 발견 된 모든 양식을 다시 살펴 보는 확인 시스템을 작성할 수 있습니다.

예를 들어 공공 재산 '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();
        }
    }
}

간단한 방법이 있습니다.

양식이 NULL인지 또는 폐기되었는지 확인하십시오. 그것이 사실이라면 우리는 양식의 새 인스턴스를 만듭니다.

그렇지 않으면 우리는 이미 실행중인 양식을 보여줍니다.

    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를 공개로 변환하고 하나의 인스턴스 만 생성해야합니다.

양식을 열기 전에 기존 프로세스를 확인할 수 있습니다.

using System.Diagnostics;

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

getProcessesByName 메소드가 UAC 또는 기타 보안 조치의 영향을 받는지 여부는 모르겠습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top