机房重构(二)--MDI窗体问题+优化的单例模式

    想了好久要不要叫优化后的单例模式的,还是承受不住这个标题的诱惑,于是乎就叫优化后的单例模式吧!

    事情的起源是这样的,先来一张图:机房重构(二)--MDI窗体问题+优化的单例模式_第1张图片

    看着有点乱我来解释一下:可以看到下机这个按钮竟然跑到学生余额查询这个窗体的上方了,也就是说主窗体的控件全部在子窗体的上方!!!这还了得,这样就不能用了啊!对于这个大家一定也有经验,问题出在MDI窗体上,然后经过本人多次试验得出结论:除非新实例化的窗体不是主窗体的子窗体,否则这是不可调和的一对矛盾!(当然你可以用类似VB中我们用过的方法一样来解决).

    如果利用我们以前一样的方法,可以添加如下的代码:

<span style="font-family:KaiTi_GB2312;font-size:18px;">using System.Runtime.InteropServices;

[DllImport("user32")]
public static extern int SetParent(int hWndChild, int hWndNewParent);

  Form2 f2 = new Form2();
  f2.MdiParent = this;
  f2.Show();
  SetParent((int)f2.Handle, (int)this.Handle);</span>

    但是相对于要实例化谁由谁来控制的单例模式来说,这段片段不太符合面向对象的思想,于是乎就大胆的决定,放弃MDI窗体的应用,为什么呢?还要从MDI窗体的源头说起.MDI窗体微软公司从Windows 2.0下的Microsoft Excel电子表格程序开始引入的,Excel电子表格用户有时需要同时操作多份表格,MDI正好为这种操作多表格提供了很大的方便,于是就产生了MDI程序.上面说的很清楚,因为同时需要打开多个表格,产生的MDI窗体,而在我们的机房中,这种需求并不是必须的,因为我们最多就是同时打开多窗体,并且在多窗体之间切换就可以了,并不存在同时操作多窗体的需求.所以放弃MDI窗体的应用,个人认为未尝不可.

    接着,在不使用MDI窗体的情况下就会产生一种情况,比方说:在上机界面下打开修改密码窗体,然后切回上机界面时,修改密码窗体任然在,却不能通过菜单选择获得焦点.这种状况应该不少人也遇到过吧,为什么呢?看代码:

<span style="font-family:KaiTi_GB2312;font-size:18px;">private static frmMOdifyPW fmp = null;
        private frmCheckCash()
        {
            InitializeComponent();
        }
        public static frmModifyPW GetInstance()
        {
            //判断当修改密码窗体不在或者消失后,激活
            if (fmp == null || fmp.IsDisposed)
            {                
                fmp = new frmCheckCash();//此处已将父窗体为MDI主窗体去掉                
            }            
            return fmp;
        }  </span>
    观察上述代码,此为设计模式中的代码片段,理解一下就是在fmp不存在或者窗口被释放时,新实例化一个窗体,但是在我们于两个窗体直接切换的时候,我们没有关闭任何一个窗体,进而触发该事件后直接返回了!而我们需要的是,要么没有窗体,实例化出来;要么窗体存在,获得焦点(好让我使用);故而在书上经典单例模式应用于非MDI窗体后我添加了一行代码,在返回之前,激活该窗体:

<span style="font-family:KaiTi_GB2312;font-size:18px;"><span style="color:#333333;"> private static frmModifyPassword fmp = null;
        private frmModifyPassword()
        {
            InitializeComponent();
        }
        public static frmModifyPassword GetInstance()
        {
            //判断当修改密码窗体不在或者消失实例化,否则激活该窗体
            if(fmp==null||fmp.IsDisposed)
            {
                fmp = new frmModifyPassword();                 
            }
            fmp.Activate();//在返回之前激活本窗体
            return fmp;
        }  </span></span>
    这样,就可以实现在各个窗体之间切换时,不必去下方的工程中选择原来的窗体了,再次点击修改密码,该窗体又会出现在程序的最上方.开始的时候比较迷信书上的代码,像金科玉律一样的奉行,但是毕竟情况千变文化,适合自己的才是最好的,我们要善于学习他人的有点,同时也要具有打破常规,突破书本的勇气.

你可能感兴趣的:(单例模式,C#)