表格之间沟通的最佳方式?

我几乎从不使用(高级或根本没有)图形界面,或者一个带有简单控件的简单forms……但这次我有一些更复杂的东西,而且我对GUI没有多少经验。 我有一个主要forms(未来可能更多),其他子forms也可以打开(并且它们可能有自己的子forms),我想知道在你看来,它们之间的最佳通信方式是什么?

我想把主窗体作为参数传递给子窗体的构造函数,但它似乎不是一个好方法,特别是如果我需要在其他不同的子窗体之间进行通信,而不是提到我必须仔细检查输入,或者做一些方法,但它似乎更像是函数式编程而不是面向对象的编程…

也许我可以:

  • 为全局设置创建静态类(或Properties.Settings)。 缺点:每次更改数据都需要复制到课堂上,我正在寻找一些更舒适和优雅的东西。
  • 使用从Application.OpenForms访问控件的丑陋方式 – 修复了将主窗体作为参数传递的问题。 缺点:不太稳定。
  • 做一些我没有想到的事情。 建议? 缺点:不知道它到底是什么。

您的构造函数可能是回到主窗体的最合理的通信方法。 您的子表单将执行以下操作:

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; } } 

或者,您可以反过来订阅SubForms中的事件:

 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 } } 

一种好方法是以想要开始通信的forms声明委托。 你需要一个委托和一个回调函数:

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

然后,另一个表单可以附加到此委托。 在那一刻,两种forms都必须彼此了解,但不是在那之后:

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

第二种forms必须声明一个与委托定义匹配的函数:

 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(); } } } 

最灵活,可扩展(以及恕我直言,最专业)的方法是使用CAB(复合应用程序块) 。 简单来说,CAB是一组2-3个程序集,它们以正确的方式实现了复杂的UI应用程序所需的大量管道,并以一种很好的方式将这个管道公开给了库的用户。 其中它有一个非常好的事件和命令(如命令模式)系统。

缺点:需要一些时间来学习,而不是很容易掌握。

这是一个全面(但易于理解)的教程 ,可以帮助您更轻松地学习。

您可以使用表单的内置Tag属性,该属性是“对象”类。

public Form1(){(ComplicatedDataStructure)Tag = new ComplicatedDataStracture(); }。 。 form1 = new Form1(); 。 。 form2 = new Form2(); 。 。 form2.Tag = form1.Tag;

所以form2.Tag等于“ComplicatedDataStracture”对象;