機房重構(二)--MDI窗體問題+優化的單例模式

    想了好久要不要叫優化後的單例模式的,還是承受不住這個標題的誘惑,於是乎就叫優化後的單例模式吧!

    事情的起源是這樣的,先來一張圖:

    看着有點亂我來解釋一下:可以看到下機這個按鈕竟然跑到學生餘額查詢這個窗體的上方了,也就是說主窗體的控件全部在子窗體的上方!!!這還了得,這樣就不能用了啊!對於這個大家一定也有經驗,問題出在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>
    這樣,就可以實現在各個窗體之間切換時,不必去下方的工程中選擇原來的窗體了,再次點擊修改密碼,該窗體又會出現在程序的最上方.開始的時候比較迷信書上的代碼,像金科玉律一樣的奉行,但是畢竟情況千變文化,適合自己的纔是最好的,我們要善於學習他人的有點,同時也要具有打破常規,突破書本的勇氣.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章