標籤:設計模式 vb.net
機房收費系統進行有一段時間了,但是始終有些曆史遺留問題。比如,如何MDI子表單如何顯示在上層的問題和MDI子表單執行個體化的問題。
對於如何顯示在上層的問題,這次採用的還是SetParent函數,在模組裡面添加:
<span style="font-size:18px;"><span style="font-size:18px;"> '定義一個用來設定子表單的函數 Declare Function SetParent Lib "user32" Alias "SetParent" (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long</span></span>
接著,要解決的就是子表單執行個體化的問題,然後查過一些方法之後,選擇了單例模式。回過頭去查自己當初學設計模式時的代碼:
<span style="font-size:18px;"> <span style="font-size:18px;">public partial class FormToolbox : Form { private static FormToolbox ftb = null; //聲明一個靜態類變數 private FormToolbox() //將構造放改成私人的,外部代碼不能直接new來執行個體化它 { InitializeComponent(); } private void FormToolbox_Load(object sender, EventArgs e) { } //得到類執行個體的方法,傳回值就是本類對象,注意,此方法也是靜態方法 public static FormToolbox GetInstance() { if (ftb == null || ftb.IsDisposed) { ftb = new FormToolbox(); ftb.MdiParent = Form1.ActiveForm; } return ftb; } }</span></span>
大的方針制定好之後,開始動手寫。。
動手的時候,才會發現,學習的時候做的DEMON其實總是非常理想化的東西,實際中面臨的問題往往更複雜。
複習了下設計模式之後,然後就開始寫自己的VB.NET版本的了,為瞭解決表單不美觀的問題,這次還是加了容器空間,load的時候平鋪表單。
但是,每次子表單彈出來,總是會閃一下,然後消失,再點擊按鈕,讓子表單彈出來,這下才會變正常。就像《超級破壞王》中的雲妮洛普一樣,
看起來就是程式中的BUG. 之後單步監視了很久,發現,調用setparent的時候,子表單因為被前置,就會出現在主表單的前面,但是在setparent之後,還是有了某某.Show()方法,這就造成了一個矛盾,setparent剛將表單置前,show方法又將表單隱藏在主表單和控制項的夾層裡面了,╮(╯▽╰)╭ 矛盾啊。改完這個之後,解決了閃現的問題。
還有單例的問題:
<span style="font-size:18px;"><span style="font-size:18px;">If IsNothing(checkBalance) Or checkBalance.IsDisposed Then '如果沒有執行個體化</span></span>
但是,每次運行到這裡的時候就會出錯:“未將對象的引用設定到對象的執行個體的問題”
細想下,剛剛聲明的對象,根本沒有new,在這行這句話的時候,IsNothing值為true,然後它會接著調用IsDisposed,這時就會出現問題,因為checkBalance根本就是Nothing嘛~這時想起了以前學習C#的時候學到的一個邏輯短路的問題:C語言的“邏輯短路”
利用邏輯短路,可以很好的解決“未將對象的引用設定到對象的執行個體的問題”。
so,只需查查VB.NET的邏輯運算子,然後我找到了OrElse。。。
代碼如下:
<span style="font-size:18px;">#Region "單例模式:用來判斷本表單是否已經執行個體化" Private Shared checkBalance As frmCheckBalance = Nothing '定義一個靜態類變數 Private Sub New() ' 此調用是 Windows 表單設計器所必需的。 InitializeComponent() ' 在 InitializeComponent() 調用之後添加任何初始化。 End Sub Public Shared Sub GetInstance() ' As frmCheckBalance '用來出現執行個體 If IsNothing(checkBalance) OrElse checkBalance.IsDisposed Then '如果沒有執行個體化 '注意:1,要判斷表單是否已被執行個體化和表單是否被銷毀過(當關閉一個表單時,資源被釋放,但是並不是nothing) ' 2,orelse產生了邏輯短路的問題,如果這裡用Or會產生錯誤,因為可能會引用不存在的對象。 checkBalance = New frmCheckBalance '執行個體化checkbanlance End If checkBalance.MdiParent = frmMain '設定父表單 checkBalance.Show() '顯示表單出來,但是此時子表單還是被隱藏在下層的,必須要通過SetParent將它拿到上層來 SetParent(checkBalance.Handle.ToInt64, frmMain.Handle.ToInt64) '設定表單置前 'Return checkBalance '返回 End Sub#End Region</span>
上面對單例模式有所改動,但是不影響單例模式的靈魂。
在主表單裡,只需調用sub 過程就好。
<span style="font-size:18px;"> Private Sub checkBalanceMenu_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles checkBalanceMenu.Click frmCheckBalance.GetInstance() End Sub</span>
PS:代碼裡面還是一點點BUG,正在修改中,希望路過的高手們指點一二~