.NET中表單間相互訪問的幾種方式

來源:互聯網
上載者:User

        在我們的程式中,表單之間經常要相互訪問彼此的成員,調用彼此的方法,或者激發彼此的事件。下面就我的經驗,簡單談談在.NET中表單間相互訪問的幾種方式。以下給出了C#.NET和VB.NET的範例程式碼。用Form1、Form2類分別表示主、從表單。

1、內部成員訪問法,適合於主表單訪問它所建立的從表單對象中的成員。只需將從表單允許主表單訪問的那些成員加上internal或Friend限定符。例如:

C#主

private void ShowForm2Info() {

    Form2 f2 = new Form2();

    f2.Show();

    MessageBox.Show(f2.MyName);

}

C#從

internal string MyName = "A Form2 Object";

VB主

Private Sub ShowForm2Info()

    Dim f2 As New Form2

    f2.Show()

    MsgBox(f2.MyName)

End Sub

VB從

Friend MyName As String = "A Form2 Object"

 2、將以上方法反過來用,讓從表單訪問建立它的主表單中的成員,需要增加一個步驟:在從表單的建構函式中傳入一個主表單的引用,以便找到建立它的主表單(建立的建構函式中不要忘了調用InitializeComponent()函數)。主表單建立從表單對象時傳入自身的引用。例如:

C#主

private void ShowForm2() {

    Form2 f2 = new Form2(this);

    f2.Show();

}

 

internal string MyName = "A Form1 Object";

C#從

private Form1 f1;

public Form2(Form1 _f1) {

    InitializeComponent();

    f1 = _f1;

}

 

private void ShowForm1Info() {

    MessageBox.Show(f1.MyName);

}

VB主

Private Sub ShowForm2()

    Dim f2 As New Form2(Me)

    f2.Show()

End Sub

 

Friend MyName As String = "A Form1 Object"

VB從

Private f1 As Form1

Public Sub New(ByVal _f1 As Form1)

    MyBase.New()

    InitializeComponent()

    f1 = _f1

End Sub

 

Private Sub ShowForm1Info()

    MsgBox(f1.MyName)

End Sub

註:我的朋友wuzhenzhi指出,對主表單的引用,通過屬性或方法傳入要比通過在建構函式中傳入好,因為“對於一個表單,沒什麼,但如果是一個使用者控制項,我們經常會像拖動Button控制項一樣從工具列裡拽下來,這時系統就會調用預設的那個建構函式,而不是你的那個重載版本,這辦法就失靈了。”這個建議有道理。

 3、從表單訪問主表單中的成員,如果主表單只有一個執行個體,或者被訪問對象是全域性的,可以將主表單中要求訪問的成員設定為靜態,加上static或Shared限定符即可:

C#主

private void ShowForm2() {

    Form2 f2 = new Form2();

    f2.Show();

}

 

internal static string MyName = "A Form1 Object";

C#從

private void ShowForm1Info() {

    MessageBox.Show(Form1.MyName);

}

VB主

Private Sub ShowForm2()

    Dim f2 As New Form2()

    f2.Show()

End Sub

 

Friend Shared MyName As String = "A Form1 Object"

VB從

Private Sub ShowForm1Info()

    MsgBox(Form1.MyName)

End Sub

 4、還可以運用.NET的事件委託機制,實現更加靈活的相互調用。下例是從表單激發主表單的事件。事件委託機制的功能事實上遠比此例強大,大家可以找書看看它的詳細用法。

C#主

private void ShowForm2() {

    Form2 f2 = new Form2();

    f2.Show();

    f2.SendMessage += new Form2.DelegateOfSendMessage(ShowMessage);

}

 

private void ShowMessage(string str) {

    MessageBox.Show(str);

}

C#從

public delegate void DelegateOfSendMessage(string str);

public event DelegateOfSendMessage SendMessage;

 

private void Send() {

    SendMessage("A Message From Form2");

}

VB主

Private Sub ShowForm2()

    Dim f2 As New Form2

    f2.Show()

    AddHandler f2.SendMessage, AddressOf ShowMessage

End Sub

 

Private Sub ShowMessage(ByVal str As String)

    MsgBox(str)

End Sub

VB從

Public Delegate Sub DelegateOfSendMessage(ByVal str As String)

Public Event SendMessage As DelegateOfSendMessage

 

Private Sub Send()

    RaiseEvent SendMessage("A Message From Form2")

End Sub

 5、同樣的道理,參考方法2和方法4可以實現主表單激發從表單的事件,這個請讀者自己實驗。當然這樣一來代碼會顯得比較亂。一個較好的解決方案是將事件封裝入一個介面,同時在事件的發布方和訂閱者實現。這種技術在.NET Remoting遠程對象操作技術中尤為重要,有一篇不錯的文章給大家參考:《Remoting事件處理全接觸》(http://www.cnblogs.com/wayfarer/articles/75213.html)

 6、習慣了VB6中全域變數的朋友可能覺得.NET中不支援全域變數對於表單間的互動很不方便,那麼再請大家參考這篇文章:《.NET表單之間的互動》(http://blog.csdn.net/warsgrobe/archive/2005/07/29/438013.aspx),裡面敘述了用VB.NET類比全域變數的方法。另外我的朋友wuzhenzhi提出了在全域模組中建立全域變數解決方案,大家可以參考他的文章:《對預設啟動表單操作的方法》(http://wuzhenzhi.blogdriver.com/wuzhenzhi/875776.html)

 7、本文發布的第二天,wuzhenzhi提醒我:事實上.NET中有一個現成的方法讓從表單訪問主表單的成員,就是帶有owner參數的Form.ShowDialog方法。這個owner便是對主表單的引用。這個快捷的方法適合於對話方塊性質的從表單(也就是說在操作從表單時不允許操作主表單),但對諸如MDI子表單等不適用。注意owner是個IWin32Window,需要強制轉化為主表單類。

C#主

private void ShowForm2() {

    Form2 f2 = new Form2();

    f2.ShowDialog(this);

}

 

internal string MyName = "A Form1 Object";

C#從

private void ShowForm1Info() {

    MessageBox.Show(((Form1)(this.Owner)).MyName);

}

VB主

Private Sub ShowForm2()

    Dim f2 As New Form2()

    f2.ShowDialog(Me)

End Sub

 

Friend MyName As String = "A Form1 Object"

VB從

Private Sub ShowForm1Info()

    MsgBox(CType(Me.Owner, Form1).MyName)

End Sub

 8、那麼對於MDI子表單有什麼好方法呢?最怕的就是看了上面的幾種方法,形成思維定勢,直接就套用了。須知矛盾有普遍性,也有特殊性,對於MDI子表單照樣有現成的方法,就是調用子表單的MdiParent屬性訪問主表單。這個想必大家都知道,放在這裡,保持文章的完整性。

C#主

private void ShowForm2() {

    Form2 f2 = new Form2();

    f2.MdiParent = this;

    f2.Show();

}

 

internal string MyName = "A Form1 Object";

C#從

private void ShowForm1Info() {

    MessageBox.Show(((Form1)(this.ParentForm)).MyName);

}

VB主

Private Sub ShowForm2()

    Dim f2 As New Form2

    f2.MdiParent = Me

    f2.Show()

End Sub

 

Friend MyName As String = "A Form1 Object"

VB從

Private Sub ShowForm1Info()

    MsgBox(CType(Me.ParentForm, Form1).MyName)

End Sub

 OK,就說到這裡。.NET是一個強大而靈活的體系,只要肯動腦筋,一定能發現不少這樣的技巧。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.