【问题标题】:Passing Data Between 3 Separate WinForms [duplicate]在 3 个单独的 WinForms 之间传递数据 [重复]
【发布时间】:2013-06-10 20:43:48
【问题描述】:

在我在 C# WinForms 领域进行编码期间,我遇到过许多在表单之间传递数据的不同方法的实例。我在一个大型代码库上工作——其中一些方法是由其他人编写的,我随后对其进行了扩展,还有一些是我自己编写的。似乎有两种主要的范式,我对这两种范式都进行了相当轻松的编码。

1.) 在实例化或显示子窗体时将父窗体传递给子窗体。例如:

    ChildForm.Instance = new ChildForm(this);

    --Or--

    ChildForm.Instance = new ChildForm();
    ChildForm.Instance.Show(this.TopLevelControl);

这允许子级从父级提取信息,并允许父级调用子级的方法。请耐心等待一下——我确实意识到这打破了很多范式,并且是“不好”的做法——请记住,我在维护一个更大的代码库期间遇到了很多这样的情况,我需要对其进行增量调整无需进行完整的重构。

2.) 使用事件委托来允许在父表单和子表单之间传输数据。据我所知,这仍然需要父表单在生成孩子时建立此事件。例如:

在父级内:

    childForm = new ChildForm(this);
    DataRead += new DataReadEventHandler(childForm.ChildForm_DataRead);

在孩子内:

    public void ChildForm_DataRead(Data data)
    {
         if (InvokeRequired)
         {
              Invoke(new MethodInvoker(delegate() { ChildForm_DataRead(data); }));
         }
         else
              //do something
    }

这种性质的东西。现在,我仍然不是 C# WinForms 的强大编码人员,但我确实意识到从设计角度来看,事件/消息传递方法可能“更好”。


现在,这是我的问题。

为了命名,我有一个主窗体:ParentForm。 ParentForm 目前使用后一种形式的消息传递(har har!)将数据传递给,比如说,FirstChildForm。本质上,ParentForm一旦获取数据,就会触发DataReadEventHandler,数据从ParentForm传递到FirstChildForm。

没问题。

现在,我/也/有一个从 ParentForm 生成的表单,称为 SecondChildForm。注意:这不是 ChildForm 的另一个实例……它是完全不同的形式。这里有一个问题——当 SecondChildForm 上的数据更新时,我希望将这些数据传递给 FirstChildForm。这似乎是一个简单的想法,尽管我在思考如何实现它时遇到了一些困难。我能想到的只是为每个孩子从 ParentForm 设置唯一的事件处理程序,然后让 SecondChildFrom 的事件处理程序触发 FirstChildForm 的 ParentForm 事件处理程序......这听起来非常令人费解,因为数据(非平凡的大小,我可能会添加),必须首先从 SecondChildForm 传递到 ParentForm,然后从 ParentForm 传递到 FirstChildForm。

有更好的方法吗?

另外,我真的不想这么说,但是,老实说,在这个高度封闭的应用程序中,如果正确的方法非常复杂,我可以为了简单而打破范式(尽管如此,我还是会在正确重构的未来——是的,我实际上 /am/ 能够做到这一点!)。

干杯!

-卡达杰

【问题讨论】:

  • 我会给你关键字——观察者模式

标签: c# winforms events delegates


【解决方案1】:

所以数据首先在第二个孩子上生成,所以在那个表单上,我们需要一个可以触发的事件来提供该数据:

public class SecondChildForm : Form
{
    public event Action<MyData> SomethingHappened;

    //Other code, including code that fires the event at some point
}

然后我们有了第一个孩子,它有一些需要调用的方法来传递数据:

public class FirstChildForm : Form
{
    public void WhenSomethingHappens(MyData data)
    {
        //Do stuff with data
    }
}

最后我们有了创建两个表单并连接适当事件处理程序的主表单:

public class ParentForm : Form
{
    public ParentForm()
    {
        FirstChildForm firstChild = new FirstChildForm();
        SecondChildForm secondChild = new SecondChildForm();

        secondChild.SomethingHappened += firstChild.WhenSomethingHappens;

        //show forms and do other stuff
    }
}

瞧。

请注意,使用这种模式,每个孩子都不知道他们的父母。它们通过事件公开父级所需的信息,并允许父级通过公共方法影响它,但它们不知道也不关心哪个类正在使用它们。父级确实知道它的子类型;它适合拥有特定子类型的实例并直接操纵它的公共成员(但不是它的内部控件,它不应该是公共的)。

【讨论】:

  • 谢谢你,Servy!这是一个很好的例子!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 2022-09-29
  • 1970-01-01
  • 2011-03-05
  • 2017-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多