C# 如何实现一个窗体只能被实例一次
发布网友
发布时间:2023-03-03 03:09
我来回答
共5个回答
热心网友
时间:2024-04-24 11:19
从面向对象设计原则上来看,使用单例模式是最佳的实现方式。由于早期设计的遗漏等问题,会导致对项目中进行单例重构十分麻烦。
出于这种情况,最合适的方式建方你还是使用类似的单例模式,实例化对象本来就应该由类自象功能实现。不应该在外部实现。目前的建方是,设计一个单例模式的接口,及接口方法。然后让窗体类去继承。缺点是由于所有的窗体可能构造函数均为公开,不能做到具体的控制。虽然能解决不会遗漏哪个窗体未处理,但对于诸多窗体的修改仍然不是解决之道。
项目工期紧时,可以考虑使用外部实现。外部实现的原理就是在打开窗体时,使用一个函数进行打开,不要直接使用窗体的函数打开,当然也不是指每个窗体中去加一个成员方法。而是新建一个类。该类传入一个窗体类型,然后在程序域中查询该类是否被实现化。在一个appdomain中,所有的实例窗体都会出现在这里(模态除话框也在)。通过appdoamin可以查询到所有实例化后的窗体,那么利用查询出的所有窗体的运行态类型(用getType方法获得),与传入的类型进行对比,如果有存在,则直接返回即可,若不存在,则进行初始化。
虽然这样参解决当前的问题,但是这毕竟不是长久之计,也就是我们常说的技术债务,客户做完验证,在正式上线前使用singleton才是正道。总之这个债务是迟早要还的,至于在什么时间是由project manager自行决定。
热心网友
时间:2024-04-24 11:19
你的意思就是子窗体只能打开一次,这个需要在你的MDI窗体增加打开子窗体判断。
代码:
/// <summary>
/// 判断窗体是否已打开
/// </summary>
private bool IsChildFormExist(Form frm)
{
if (frm == null) return false;
foreach (Form childFrm in this.MdiChildren)
{
//用子窗体的Name进行判断,如果存在则将他激活
if (childFrm.Text == frm.Text)
{
childFrm.Activate();
return true;
}
}
return false;
}
/// <summary>
/// 打开窗口
/// </summary>
private void ShowForm(Form frm)
{
frm.MdiParent = this;
frm.Show();
}
调用事件里面:
if (!this.IsChildFormExist(this.frmGoodList))
{
this.frmGoodList = new SaasForce.StoreManager.Good.ListForm();
this.ShowForm(this.frmGoodList);
}
热心网友
时间:2024-04-24 11:20
可以考虑使用扩展方法,只是调用的地方进行修改,不建议使用 标题来判断
虽然同一个窗体,标题很有可能不一样,如一些订单详情,标题可能带了订单号...
从业务和可读性来说也不应该这么做.
热心网友
时间:2024-04-24 11:20
以前我用vb.net写过一个东西,思路说一下,不知道是不是你需求的
一个窗体加载器,类似工厂模式那样,由它负责调度你所用到的Form对象
加载器里有一个字典Dictionary[T,Form] where T : Form
请求时,传递目标窗体的类型泛型,然后加载器在字典中查询是否有实例,有就返回,没有就新建一个再返回
销毁的时候也一样
热心网友
时间:2024-04-24 11:21
继承也不行吗?追问说说您的理解。
追答所有窗体都继承自Form,你自己写一个MyForm加上你要的逻辑,再把每个窗体类声明从原来的基类Form改成你自己的MyForm