做WinForm,尤其是管理系統,常常需要同一個視窗僅開啟一個執行個體。也就是當這個視窗沒有建立時,則建立視窗並顯示;當視窗已存在時,則將其置於頂層並啟用。
從設計模式的角度講,應該算作單件模式(Singleton)了。
關於實現單件模式,可以參考http://terrylee.cnblogs.com/archive/2005/12/09/293509.html
介紹的比較詳細了。
下面主要是針對視窗的單件模式。
視窗的單件也可通過在表單類中寫幾句代碼簡單實現:
public partial class Form1 : Form<br /> {<br /> private static Form1 instance = null;<br /> public static Form1 Instance<br /> {<br /> get<br /> {<br /> if (instance == null)<br /> {<br /> instance = new Form1();<br /> }<br /> return instance;<br /> }<br /> }<br /> private Form1()<br /> {<br /> InitializeComponent();<br /> }<br /> private void Form1_FormClosed(object sender, FormClosedEventArgs e)<br /> {<br /> instance = null;<br /> }<br /> }
1. 將建構函式改為private
2. 添加靜態屬性Instance
3. 視窗關閉事件中,將instance置為null;
這樣,便可以通過Form1.Instance產生唯一的視窗執行個體。
但是這樣做,有很多不足:
1. 當Mdi主表單中有很多子表單,這些子表單都要添加類似的重複代碼。
2. 如果一個子表單要調用另一個子表單,並且不想跟從主表單中開啟的相同(即再建立一個視窗),則無法實現。(其實將建構函式改為public也可以實現,但又不算嚴格的單件了)
因此,最好通過寫一個單獨的類,通過這個類產生單件表單。
顯然,要用泛型實現:
/// <summary><br /> /// 泛型實現表單執行個體單件化<br /> /// </summary><br /> /// <typeparam name="T">表單類</typeparam><br /> public static class Singleton<T> where T : Form, new()<br /> {<br /> private static T instance = null;<br /> private static readonly object lockHelper = new object();<br /> /// <summary><br /> /// 擷取表單的唯一執行個體<br /> /// </summary><br /> public static T Instance<br /> {<br /> get<br /> {<br /> if (instance == null)<br /> {<br /> lock (lockHelper)<br /> {<br /> if (instance == null)<br /> {<br /> instance = new T();<br /> instance.FormClosed +=new FormClosedEventHandler(DestroyForm);<br /> }<br /> }<br /> }<br /> return instance;<br /> }<br /> }<br /> /// <summary><br /> /// 當表單關閉時將Instance置空<br /> /// </summary><br /> /// <param name="sender"></param><br /> /// <param name="e"></param><br /> private static void DestroyForm(object sender, FormClosedEventArgs e)<br /> {<br /> instance = null;<br /> }</p><p> }
where T : Form, new()表示T必需是Form且具有無參建構函式。
lockHelper是為了多安全執行緒,可參考上面的連結。
在產生新的表單類時,instance.FormClosed +=new FormClosedEventHandler(DestroyForm);註冊委託實現當表單關閉時,將instance置空。
這樣便實現了任何一個普通的表單類,都可以通過調用此泛型類,產生單件表單。
調用時,只要Singleton<ChildForm>.Instance
便可獲得由這個類產生的ChildForm表單的唯一執行個體。
當然,也可在MDI主表單中寫一個泛型函數,方便顯示子表單:
/// <summary><br /> /// 顯示表單,共置於最前端<br /> /// </summary><br /> /// <typeparam name="T"></typeparam><br /> private void ShowForm<T>()<br /> where T : Form, new()<br /> {<br /> T f = Singleton<T>.Instance;<br /> f.MdiParent = this;<br /> f.Show();<br /> if (f.WindowState == FormWindowState.Minimized)<br /> f.WindowState = FormWindowState.Normal;<br /> f.BringToFront();<br /> }