2010-12-14 125 views
3

我幾乎從不使用(高級或者所有)圖形界面,或者使用簡單的控件來完成一個簡單的表單......但是這次我已經有了一些更復雜的東西,而且我對GUI沒有太多的經驗。 我有一種主要的形式(可能還有更多的未來),其他子表單可以從其中打開(並且它們可能有自己的子表單),我想知道什麼是您認爲它們之間進行通信的最佳方式?表單之間的最佳溝通方式?

我想過將主窗體作爲參數傳遞給子窗體的構造函數,但它看起來並不是一種好方法,特別是如果我需要在其他不同的子窗體之間進行通信時-forms,何況我必須仔細檢查輸入,或做一些方法,但它似乎更像是一個比面向對象的編程功能編程...

或許我可以:

  • 創建靜態類(或Properties.Settings)用於全局設置。缺點:每一次數據更改都需要複製到課堂上,我正在尋找更舒適和優雅的東西。
  • 使用醜陋的從Application.OpenForms訪問控件的方式 - 修復了傳遞主窗體作爲參數的問題。缺點:不太穩定。
  • 做別的事我沒有想過。建議?缺點:不知道它是什麼。
+0

如何使主窗體的子窗體屬性? [形式之間溝通]的 – kenny 2010-12-14 11:33:00

+0

可能重複(http://stackoverflow.com/questions/4373660/communicating-between-forms) – 2010-12-14 12:11:07

+0

答案是這裏 [通訊兩者中的C#Windows形式] [1] [1]:http://stackoverflow.com/questions/1665533/communicate-between-two-windows-forms-in-c-sharp – 2014-07-27 17:44:53

回答

1

您的構造函數的想法可能是回到主窗體的最健全的通信方法。你的子表單會做類似如下:

public class SubForm : Form 
{ 
    public SubForm(MainForm parentForm) 
    { 
     _parentForm = parentForm; 
    } 

    private MainForm _parentForm; 

    private void btn_UpdateClientName_Click(object sender, EventArgs e) 
    { 
     _parentForm.UpdateClientName(txt_ClientName.Text); 
    } 
} 

然後你暴露在你的MainForm公共方法:

public class MainForm : Form 
{ 
    public void UpdateClientName(string clientName) 
    { 
     txt_MainClientName.Text = clientName; 
    } 
} 

或者,你可以四處走另外一條道路,並訂閱您的子表單事件:

public class MainForm : Form 
{ 
    private SubForm1 _subForm1; 
    private SubForm2 _subForm2; 

    public MainForm() 
    { 
     _subForm1 = new SubForm1(); 
     _subForm2 = new SubForm2(); 

     _subForm1.ClientUpdated += new EventHandler(_subForm1_ClientUpdated); 
     _subForm2.ClientUpdated += new EventHandler(_subForm2_ProductUpdated); 
    } 

    private void _subForm1_ClientUpdated(object sender, EventArgs e) 
    { 
     txt_ClientName.Text = _subForm1.ClientName; // Expose a public property 
    } 

    private void _subForm2_ProductUpdated(object sender, EventArgs e) 
    { 
     txt_ProductName.Text = _subForm2.ProductName; // Expose a public property 
    } 
} 
+0

這種方法的問題是,我想在未來與更多表單進行交流,如兩個不同的子表單。 – Symbol 2010-12-14 11:40:35

+0

@Symbol - 查看我的替代示例。 – GenericTypeTea 2010-12-14 11:41:32

+0

會做第一個例子還暴露_internal_方法和變量? – Josh 2012-02-13 09:22:22

0

您可以使用「對象」類窗體的內置Tag屬性。

public Form1() {複製數據結構(Tag)= new ComplicatedDataStracture(); } 。 。 form1 = new Form1(); 。 。 form2 = new Form2(); 。 。 form2.Tag = form1.Tag;

所以form2.Tag等於「ComplicatedDataStracture」對象;

+0

我有很多屬性,如果我想使用這種方法,我需要創建某種數據結構,並且在決定要做什麼之前我正在尋找其他方法。 – Symbol 2010-12-14 11:45:48

0

最靈活,可擴展(和恕我直言最專業)的方法是使用CAB (Composite Application Block)。簡單來說,CAB是一組2-3個組件,它們實現了許多管道工程,這些管道需要製作複雜的UI應用程序正確的方式,並以良好的方式向庫的用戶公開此管道。其中有一個非常好的事件和命令(如命令模式)系統。

缺點:需要一些時間來學習,而不是很微不足道的把握。

這是一個comprehensive (but easy to understand) tutorial這將幫助您使學習更容易。

+0

謝謝,即使我正在尋找更直接的東西,無需安裝任何新東西或學習如何使用它。 如果我將使用它,我是否需要對當前項目,代碼和/或GUI進行很多更改? – Symbol 2010-12-14 11:54:15

+0

@Symbol取決於您目前的代碼是如何組織/編寫的。它可能不是很簡單,但也不是很難。取決於您當前的代碼。但請注意,您不必使用lib的每個部分。你可以拿你需要的。 – 2010-12-14 12:01:14

+0

@Symbol「安裝」是最簡單的部分。只需將refenrece添加到3個庫並使用這些功能即可。知道如何使用它們可能是一個小問題。但是,如果將來會製作更多的winform應用程序,至少應該有關於它的基本知識。 – 2010-12-14 12:03:50

1

一個好方法是以希望開始通信的形式聲明委託。您需要代理和回撥功能:

public delegate void SetValueDelegate(string value); 
public SetValueDelegate SetValueCallback; 

另一種形式可以附加到此代表。在那一刻,這兩種形式都知道對方,但片刻後沒有:

firstForm.SetValueCallback += new SetValueDelegate(secondForm.SetValueFunction); 

第二種形式有權宣佈該委託定義相匹配的功能:

public void SetValueFunction(string value) 
{ 
    // do something 
} 

現在第一種形式可以使用委託使用第二形式的附着到委託所有其它形式或類功能(和:

SetValueCallback(txtParam.Text); 

編輯:做了一個完整的例子

using System; 

namespace DelegateTest 
{ 
    public delegate void SetValueDelegate(string value); 

    public class Class1 
    { 
     public SetValueDelegate SetValueCallBack; 

     public void Test() 
     { 
      if(SetValueCallBack != null) 
      { 
       SetValueCallBack("Hello World!"); 
      } 
     } 
    } 

    public class Class2 
    { 
     public void SetValueFunction(string value) 
     { 
      Console.WriteLine(value); 
     } 
    } 

    public class Launcher 
    { 
     public static void Main(string[] args) 
     { 
      Class1 c1 = new Class1(); 
      Class2 c2 = new Class2(); 
      c1.SetValueCallBack += new SetValueDelegate(c2.SetValueFunction); 
      c1.Test(); 
     } 
    } 
} 
+0

+1,我沒有看過你的代碼,但你做了一個很好的嘗試。 – 2010-12-19 19:48:38

+4

你沒有讀他的代碼,跛腳 – Thomas 2011-05-26 08:31:31