分享

两个窗体之间通讯的方法

 nxhujiee 2010-04-15
两个窗体之间通讯的方法
作者:Larry Nung    来源:Level Up     更新时间:2009-11-16

常會看到有人詢問兩個表單間的資料要如何互通,重覆詢問率之高讓該問題約可列入初學者必問的前幾大問題了,光在程式設計俱樂部大概這類問題我大概就已回答過4~5次了。最近又在批踢踢討論版中看到有人詢問,索性想說乾脆就整理一篇以後直接貼連結好了。

基本上要讓兩個表單間的資料達到互通大概有下列兩種方法:

方法一 使用Public欄位、屬性、或方法互通表單資料

 image

如上圖所示,假設今天我們有兩個表單Form1跟Form2,且Form2由Form1所叫起,在這樣的條件之下,若Form1想要取得Form2上面的資料,相信應該對大家來說都不是問題,直接在Form1上使用Form2的Public欄位、屬性、或方法就可以了。如下程式所示,透過這些Public的成員,我們很容易的可以把Form1的資料送給Form2,也很容易的可以由Form1把Form2上的資料取回。

舉個例子來說,假如Form2內的資料存取範圍為Public或是Friend(控制項的話則如下圖把Modifiers屬性值設為Public或是Friend)。

 image

image

則我們可以在Form1中透過Form2的物件參考直接去控制Form2的控制項或是內部的資料。

VB.NET

'透過Form2的Public成員把Form1的資料送給Form2
Form2.NumericUpDown1.Value = Me.NumericUpDown1.Value

C#

//透過Form2的Public成員把Form1的資料送給Form2
Form2.NumericUpDown1.Value = this.NumericUpDown1.Value;

 

很簡單吧?不過這並不是很好的寫法,因為此種寫法違反了物件導向的封裝原則。較好的寫法是利用屬性去封裝,首先我們需要把Form2的資料存取範圍設為Private(控制項的話則如下圖把Modifiers屬性值設為Private),讓類別外無法直接做存取的動作。

image

接著,我們可以撰寫如下的Code,利用屬性封裝Form2的控制項甚至是內部的資料。

VB.NET

    Property Value() As Decimal
        Get
            Return NumericUpDown1.Value
        End Get
        Set(ByVal value As Decimal)
            NumericUpDown1.Value = value
        End Set
    End Property

C#

public decimal Value {
    get { return NumericUpDown1.Value; }
    set { NumericUpDown1.Value = value; }
}

 

用屬性封裝好後我們就可以在Form1中透過Form2的物件參考,藉由Form2的Public屬性控制Form2的控制項或內部的資料。

VB.NET

Form2.Value = 123
 

 

C#

Form2.Value = 123;

 

介紹完Form1如何取得Form2上面的資料後,反過來要是Form2想要主動取得或設定Form1的資料呢?其實也很簡單,如下程式所示,只要把上面的概念活用,在Form2被Form1叫起後透過建構子或Public屬性把Form1的物件參考傳到Form2內,Form2就可以用Form1傳進來的物件參考對Form1內的Public成員做想要的動作。

VB.NET

Public Class Form1  
...
      'Form1透過Form2的Public成員把自身的物件參考傳入Form2
      Form2.MainForm = Me
...
End Class

Public Class Form2
...
      Public MainForm As Form1
...
      'Form2透過Form1傳進的物件參考控制Form1
      MainForm.Value = Me.NumericUpDown1.Value
...
End Class

 

C#

Public Class Form1
{ 
...
      //Form1透過Form2的Public成員把自身的物件參考傳入Form2
      Form2.MainForm = this;
...
}
 
Public Class Form2
{
...
      Public Form1 MainForm;
...
      //'Form2透過Form1傳進的物件參考控制Form1
      MainForm.Value = this.NumericUpDown1.Value;
...
}

 

 

值得注意的是,上述方法我是為了示範較簡單的方式才會把Form1的物件參考傳入Form2,實際使用上,能避免這樣寫還是建議盡量避免,因為這樣會讓Form1跟Form2的耦合性提高,較好的方法是Form2內定義一些對應的事件,Form1在這些事件觸發時再利用Form2的物件做對應的處理。

程式大概如下:

Public Class Form1
...
       AddHandler Form2.SetValueToForm1, AddressOf OnSetValueToForm1
...
   Private Sub OnSetValueToForm1(ByVal sender As Object, ByVal e As EventArgs)
        Me.NumericUpDown1.Value = Form2.Value        '把Form2的資料送給Form1
    End Sub
...
End Class  '更多.net源码和教程,来自[乐博网 www.]
 
Public Class Form2
...
   Event SetValueToForm1 As EventHandler
 
    Protected Sub OnSetValueToForm1(ByVal e As EventArgs)
        RaiseEvent SetValueToForm1(Me, e)
    End Sub
 
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        OnSetValueToForm1(New EventArgs)       
    End Sub
...
End Class
 

P.S.這邊初學者很容易犯的問題就是會在Form2內再宣告出一個Form1,並對宣告出的Form1做資料互傳,最後的結果當然是資料互傳後結果不如預期。這是因為沒認清物件參考的原因,每宣告一個物件實體作業系統都會分配一塊記憶體空間,因此需認清本來的Form1表單與Form2內新宣告的Form1是不同的物件參考這個事實。

 

方法二 透過靜態變數互通表單資料

透過靜態變數也是可以互通表單資料的方法,使用起來很簡單,只要宣告個靜態變數,接著把該靜態變數指向物件參考,則程式內就可透過該靜態變數做資料的互通,但是該方法較不建議採用。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多