如何在c#中避免多个windows窗体实例
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在c#中避免多个windows窗体实例相关的知识,希望对你有一定的参考价值。
如何在c#中避免多个windows窗体实例?我只想运行一个表单实例。因为有可能从我的应用程序的许多页面打开相同的表单。
一个例子:CodeProject: Simple Singleton Forms(好吧,它在VB.NET中,但只是为了给你一个线索)
单身人士不是面向对象的。它们只是全局变量的对象版本。你可以做的是使Form类的构造函数为private,所以没有人可以意外地创建其中的一个。然后调用反射,将ctor转换为public,并确保创建一个且只有一个实例。
您可以在打开表单之前检查现有流程:
using System.Diagnostics;
bool ApplicationAlreadyStarted()
{
return Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length == 0;
}
我不知道GetProcessesByName方法是否受UAC或其他安全措施的影响。
是的,它有单身模式,
用于创建单个对象的代码,
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;
}
检查这个link:
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;
}
}
以上是关于如何在c#中避免多个windows窗体实例的主要内容,如果未能解决你的问题,请参考以下文章