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

时间:2010-12-14 11:31:01

标签: c# winforms user-interface

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

我想把主窗体作为参数传递给子窗体的构造函数,但它似乎不是一种好方法,特别是如果我需要在其他的,不同的,子表单,更不用说我必须仔细检查输入,或者做一些方法,但它似乎更像是函数式编程而不是面向对象的编程...

也许我可以:

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

4 个答案:

答案 0 :(得分: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;
    }
}

或者,您可以反过来订阅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
    }
}

答案 1 :(得分: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();
        }
    }
}

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

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

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

这是一个comprehensive (but easy to understand) tutorial,可以帮助您更轻松地学习。