Henry手記-VB.net WinForm中的FORM初探(二) (轉)

worldblog發表於2007-12-12
Henry手記-VB.net WinForm中的FORM初探(二) (轉)[@more@]

Henry手記- 中的FORM初探(二)

韓睿 (2002.9.25)

 

二、怎麼樣切換兩個窗體?

在上一節中,我們認識到vb.net窗體的新特性,也知道了怎麼樣show出一個窗體了。那麼面對一個這樣的需求(也是真實的提得較多的問題)。怎麼樣實現兩個視窗間的切換。即:

窗體一:Form1,上面有個button1

窗體一:Form2,上面有個button2

點選button1,會show出Form2;點選button2,會show出Form1。

如果在中,我們還真不用費工夫寫文章來討論了//hehe。上一節中我們討論的是 與 Visual Basic6 在窗體處理機制上的關鍵區別——你只有先建立窗體例項,然後才可以顯示窗體外觀、訪問窗體屬性及其。:namespace prefix = o ns = "urn:schemas--com::office" />

這節中討論的是另一個區別:Visual Basic 6.0 專案自動建立的預設窗體例項都能被當成全域性變數使用,也就是說,專案中的任何程式碼都能直接引用窗體,並且每次被引用的都是該窗體的同一個例項。Vb.net呢?是不能這樣做了。

我們先來做個小實驗,來加深類與的概念。

你在一個窗體frmMain裡,放四個按鈕,在每個按鈕的click事件裡寫上:

dim frm1 as new form1

frm1.show

那麼,你將會看到四個一模一樣的form1。

明白了吧?但此form1非彼form1,都是form1類的一個個例項化的內容。

所以我們不能指望在的時候,命名一個區域性的frm1就能一直都對form1的例項進行控制,這是不可能的。

也就是說,在button1的click事件中寫:

dim frm2 as new form2

frm2.show

me.h

在button2的click事件中寫:

dim frm1 as new form1

frm1.show

me.hide

是有問題的,你發現問題在哪了嗎?就在於click事件中寫的都是區域性變數,每一次都會新生成一個Form的例項,而hide起來的那個form的例項卻再也show不回來了。如果不在form的closing(關閉時觸發)或其它類似事件中做任何處理,該的程式是不會停止的,這是由於做為主執行緒的第一個form1是被hide起來了,它還在執行著,程式當然不會終止嘍。

解決方法有很多,比如

1)  在module中定義Form的全域性變數

2)  用share變數模擬vb6中窗體切換的實現

一個一個說明一下吧,希望對朋友們有所啟發:

1) 在module中定義Form的全域性變數

給程式工程加一個模組,用於存放公用變數,及啟動控制用:


'Module1.vb


Module Module1


  Public F1 As New Form1()  ‘定義Form1的公用變數例項


  Public F2 As New Form2() ‘定義Form1的公用變數例項


  Sub Main()


  Application.Run(F1) ‘這句話表明程式啟動了modele後,會接下來啟動f1,即form1的一個例項


  End Sub


End Module


 


'Form1.vb


Class Form1


  ...


  Private Sub Button1_Click(ByVal sender As System., ByVal e As System.EventArgs) Handles Button1.Click


  F2.Show()  '利用公用變數


 F1.hide()


  End Sub


End Class


 


'Form2.vb


Class Form2


  ...


  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click


  F1.Show()


  F2.Hide()


  End Sub


End Class


 


同時請在:解決方案管理器-〉application1.sln -〉右點滑鼠 -〉屬性 -〉通用屬性->常規->啟動物件 -〉改為Module1

上面最後一句話的意思是讓程式在啟動時先Module1中的程式碼。初始化兩個Form的公用變數,程式入口在它的sub main,用於啟動F1(Form1的例項)。用這個方法,我們可以完成很多窗體間控制元件控制(比如Form1上的操作結果顯示到Form2的文字框中去)和資料傳遞。在這裡要注意的是,只有關閉了F1窗體,程式才會被終止。我們可以做一些處理,比如在Form的closing事件里加入end等等。

但在vb.net中其實是不贊成使用公用變數的,一是由於生存期的管理,二是引用時的混亂問題。那麼我們還有沒有其它的解決方法?

2)  用share變數模擬vb6中窗體切換的實現

其實有個最簡單但是極有用的方法,不知道您想到了嗎?就是利用vb.net自帶的升級嚮導工具進行升級呀!(儘管很多人罵這個工具不行,但有的工作它還是可以做得很好的)

我就這樣做了,先在vb6中寫了兩個Form,

Form1:

Private Sub Command1_Click()

  Form2.Show

  Me.Hide

End Sub

 

Private Sub Form_Unload(Cancel As Integer)

  End  ’關閉Form1,程式結束

End Sub

 

Fomr2:

Private Sub Command2_Click()

 Form1.Show

 Me.Hide

End Sub

Private Sub Form_Unload(Cancel As Integer)

  Form1.Show  關閉Form2,喚出Form1

End Sub

 升級後,多了一組用Region折起來的“升級支援”

Form1:

  #Region "升級支援"

  Private Shared m_vb6FormDefInstance As Form1

  Private Shared m_InitializingDefInstance As Boolean

  Public Shared Property DefInstance() As Form1

  Get

    If m_vb6FormDefInstance Is Nothing OrElse m_vb6FormDefInstance.IsDisposed Then

    m_InitializingDefInstance = True

    m_vb6FormDefInstance = New Form1()

    m_InitializingDefInstance = False

    End If

    DefInstance = m_vb6FormDefInstance

  End Get

  Set

    m_vb6FormDefInstance = Value

  End Set

  End Property

#End Region

  Private Sub Command1_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click

    Form2.DefInstance.Show()

    Me.Hide()

  End Sub

  Private Sub Form1_Closed(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Closed

  End

  End Sub

在Form2中,除了升級支援外的程式碼是:

Private Sub Command2_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles Command1.Click

    Form1.DefInstance.Show()

    Me.Hide()

  End Sub

  Private Sub Form2_Closed(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles MyBase.Closed

    Form1.DefInstance.Show()

  End Sub

  在上面的程式碼中,要注意的是是用Form1.DefInstance.Show()來show出Form1的一個例項。DefInstance 是 Shared的屬性,它能以 “窗體名.DefInstance” 的形式直接訪問。它所在專案中的任何程式碼訪問它都將得到同一個窗體例項。

這樣,我們就能模擬 vb6完成的專案對窗體的直接引用了,只不過在程式碼中以 Form1.DefInstance 代替 Form1 而已。如果要設定窗體上的一個label的內容,現在是這樣用了:Form1.DefInstance.Label1.text=”Henry”

我們完全可以copy下“升級支援”這一段程式碼,然後注意我上兩段寫的內容,就可以不用升級工具,而自己動手寫了。

 

----

  宣告:本文版權與解釋權歸韓睿所有,如需轉載,請保留完整的內容及此宣告。

qq: 18349592

 

 

 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992053/,如需轉載,請註明出處,否則將追究法律責任。

相關文章