Как избежать нескольких экземпляров формы Windows в С#
Вопрос
Как избежать нескольких экземпляров формы окон в С#??я хочу, чтобы работал только один экземпляр формы.Потому что есть вероятность открытия одной и той же формы на многих страницах моего приложения.
Решение
реализовать шаблон 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 или другие меры безопасности.