C#에서 여러 Windows 형태의 인스턴스를 피하는 방법
문제
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 또는 기타 보안 조치의 영향을 받는지 여부는 모르겠습니다.