單例模式——解決MDI子表單執行個體化的問題

來源:互聯網
上載者:User

標籤:設計模式   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,正在修改中,希望路過的高手們指點一二~

   

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.