C#でWindowsフォームの複数のインスタンスを回避する方法
質問
c#でwindowsフォームの複数のインスタンスを避ける方法は??フォームのインスタンスを1つだけ実行したい。私のアプリケーションの多くのページから同じフォームを開く可能性があるためです。
解決
例: CodeProject:Simple Singleton Forms (OK、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();
ダイアログを表示するときは、 .Show();
.ShowDialog();
を使用します。 このフォームを再び前面に表示するためにプロジェクトに適用したソリューションの1つは次のとおりです。
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フォームのクラス名であり、 戻り値は、新しいフォームインスタンスを作成しないために使用できます。
システムが異なるインスタンスデータに対して同じタイプのフォームを表示する可能性がある場合、既存の開いているすべてのフォームを反復するチェックシステムを作成して、一意のインスタンスデータ識別子を探し、見つかったフォームを再表示できます。
e.g。パブリックプロパティ「CustomerUniqueID」を含むフォームクラス「CustomerDetails」を持つ:
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;
}
}
シングルトンはオブジェクト指向ではありません。これらは、単にグローバル変数のオブジェクトバージョンです。できることは、Formクラスのコンストラクタをプライベートにすることです。そうすれば、これらの1つを誤って作成することはできません。次に、リフレクションを呼び出して、ctorをpublicに変換し、そのインスタンスを1つだけ作成してください。
フォームを開く前に既存のプロセスを確認できます:
using System.Diagnostics;
bool ApplicationAlreadyStarted()
{
return Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length == 0;
}
GetProcessesByNameメソッドがUACまたは他のセキュリティ対策の影響を受けるかどうかはわかりません。